java实体默认值-java反射的优缺点有哪些?-八维java培训
TYPE_USE
作用范围:任意使用类型的地方
@Retention:表示需要在什么级别保存该注解信息,用于描述注解的生命周期(SOURCE
类型
描述
SOURCE
生命周期只保留在源码
CLASS
生命周期保留到.class编译阶段
RUNTIME
生命周期保留到jvm运行阶段
@Document:说明该注解将被包换在javadoc中
@Inherited:说明子类可以继承父类中的注解
4.自定义注解
使用@Interface自定义注解时,自动继承了java.lang.annotation接口
package com.xiaoxian.missyou.annotion;
import java.lang.annotation.*;
@MyAnnotion(num = 0,friends = {"123","456"})
public class AnnotionTest {
}
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotion{
String name() default "";
int num();
String[] friends() default {"123","456"};
}
二、反射1.什么是反射
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期间借助Reflection API取得任何类得内部信息,并能直接操作任意对象的内部属性及方法。
类加载完后,在堆内存的方法区中就产生一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。
正常方式:引入包名 ---> new实例化 ----> 取得实例化对象
反射方式:实例化对象 -----> getClass()方法 ------> 得到完整的包名
2.反射机制提供的功能3.反射的优缺点
优点:可以实现动态创建对象和编译,体现出很大的灵活性。
缺点:对性能有影响,这类操作总是慢于直接执行相同的操作。通过invoke()调用方法的时候,可以先使用setAccessible(true)方法,取消java语言访问检查java实体默认值,可以提高一点点性能。
4.通过反射获取class对象
package com.xiaoxian.missyou.inject;
import lombok.Data;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
Class> c1 = Class.forName("com.xiaoxian.missyou.inject.Student");
Class> c2 = Class.forName("com.xiaoxian.missyou.inject.Student");
//获取的classd对象都是同一个对象,因为只有一个class对象
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
Person person = new Student();
//方式一:通过对象获取class对象
Class c3 = person.getClass();
System.out.println(c3.hashCode());
//方式二:forname()获取class对象
Class c4 = Class.forName("com.xiaoxian.missyou.inject.Student");
System.out.println(c4.hashCode());
//方式三:通过类名.class获取class对象
Class c5 = Student.class;
System.out.println(c5.hashCode());
//方式四:基本类型的包装类可以通过Type属性获取class对象
Class c6 = Integer.TYPE;
System.out.println(c6.hashCode());
//获取父类的class对象
Class c7 = c3.getSuperclass();
System.out.println(c7.hashCode());
}
}
@Data
class Person {
private String name;
}
@Data
class Student extends Person{
private Integer age;
}
5.哪些类型可以有Class对象
package com.xiaoxian.missyou.inject;
import java.lang.annotation.ElementType;
import java.util.Map;
public class Test2 {
public static void main(String[] args) {
Class c1 = Object.class;//类
Class c2 = Map.class;//接口
Class c3 = String[].class;//一维数组
Class c4 = String[][].class;//二维数组
Class c5 = Override.class;//注解
Class c6 = ElementType.class;//枚举
Class c7 = Integer.class;//基本数据类型
Class c8 = void.class;//void
Class c9 = Class.class;//class
}
}
6.获取运行时类的完整结构
package com.xiaoxian.missyou.inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test3 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Class c1 = Student.class;
//获取类的名字
System.out.println(c1.getName());//获取 包名+类名
System.out.println(c1.getSimpleName());//获取类名
//获取类的属性
System.out.println("================================");
Field[] fields = c1.getFields();//只能获取public的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("================================");
Field[] declaredFields = c1.getDeclaredFields();//获取全部属性
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//获取指定属性
Field age = c1.getDeclaredField("age");
System.out.println(age);
//获取类的方法
System.out.println("================================");
Method[] methods = c1.getMethods();//获取本类+父类的全部public方法
for (Method method : methods) {
System.out.println(method);
}
Method[] declaredMethods = c1.getDeclaredMethods();//获取本类所有方法
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//获取指定的方法
Method getAge = c1.getMethod("getAge", null);
Method setAge = c1.getMethod("setAge", Integer.class);
System.out.println(getAge);
System.out.println(setAge);
//获取构造方法
System.out.println("================================");
Constructor[] constructors = c1.getConstructors();//获取public的构造方法
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor[] declaredConstructors = c1.getDeclaredConstructors();//获取全部的构造方法
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
Constructor declaredConstructor = c1.getDeclaredConstructor();
System.out.println("指定构造器:" + declaredConstructor);
}
}
7.动态创建对象执行方法
package com.xiaoxian.missyou.inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test4 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c1 = Student.class;
//方式一:本质调用了类的无参构造函数,并且要求该无参构造函数为public
Student student = (Student)c1.newInstance();
System.out.println(student);
//方式二:通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(Integer.class);
Student student2 = (Student) constructor.newInstance(18);
System.out.println(student2);
//通过反射调用普通方法
Method setAge = c1.getDeclaredMethod("setAge", Integer.class);
setAge.invoke(student, 19);
System.out.println(student.getAge());
//通过反射操作属性
System.out.println("==========================================");
Field age = c1.getDeclaredField("age");
//不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
age.setAccessible(true);
age.set(student, 20);
System.out.println(student.getAge());
}
}
注意:Object invoke(Object obj,Object ... args)
8.通过反射获取泛型
为了通过反射操作这些类型,Java新增了ParameterizedTypejava实体默认值,GenericArrayType,TypeVariable和WidcardType几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型。
package com.xiaoxian.missyou.inject;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Test5 {
public void test01(Map map, List list) {
System.out.println("test01");
}
public Map test02() {
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Class c1 = Test5.class;
Method test01 = c1.getDeclaredMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = test01.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("===" + genericParameterType);
if (genericParameterType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("=======================================");
Method test02 = c1.getDeclaredMethod("test02");
Type genericReturnType = test02.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
9.通过反射操作注解
package com.xiaoxian.missyou.inject;
import lombok.Data;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test6 {
public static void main(String[] args) {
Class c1 = User.class;
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取指定的注解的值
MyTable myTable = (MyTable)c1.getAnnotation(MyTable.class);
System.out.println(myTable.value());
//获取类上字段的注解
Field[] declaredFields = c1.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("=======================");
MyField myField = (MyField) declaredField.getAnnotation(MyField.class);
System.out.println(myField.columnName());
System.out.println(myField.type());
System.out.println(myField.length());
}
}
}
@Data
@MyTable("db_user")
class User{
@MyField(columnName = "db_user_id", type = "Long", length = 10)
private Long id;
@MyField(columnName = "db_user_name", type = "String", length = 128)
private String name;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyTable {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyField {
String columnName();
String type();
int length();
}