反射:Reflection

一个类在内存中只有一个Class对象,hashCode值都一样
一个类被加载后,类的整个结构都会被封装在Class对象中

实体类:pojo,entity以及自定义注解

@Table("db_user")
class User{
@Filed(columnName = "db_name",type = "varchar")
private String name;
@Filed(columnName = "db_id",type = "int")
private int id;
@Filed(columnName = "db_age",type = "int")
private int age;

public User() {
}

public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}

@Override
public String toString() {
return "user{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
private void love(){
System.out.println("love");
}
}

//自定义注解
@Target(ElementType.TYPE)//表示类名注解
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
String value();
}
@Target(ElementType.FIELD)//表示属性注解
@Retention(RetentionPolicy.RUNTIME)
@interface Filed{
String columnName();
String type();
}
 

 

1.Class类的三种创建方式

  • Class.forName("xxx");
  • 类名.class;
  • 对象名.getClass();
public static void main(String[] args) throws ClassNotFoundException {
        //三种方式:类的Class对象
        Class aClass1 = Class.forName("com.bacon.reflect.User");

        Class aClass2 = User.class;

        User user = new User();
        Classextends User> aClass3 = user.getClass();
        //一个类在内存中只有一个Class对象,hashCode值都一样
        //一个类被加载后,类的整个结构都会被封装在Class对象中
        System.out.println(aClass1.hashCode());//21685669
        System.out.println(aClass2.hashCode());//21685669
        System.out.println(aClass3.hashCode());//21685669

    }

结果 

21685669
21685669
21685669

  

类的加载过程:加载,链接,初始化(这里不细化)

2.获取运行时类的完整结构

  • Field 字段
  • Method 方法
  • Constructor 构造函数
  • Superclass 父类
  • Inerface 接口
  • Annotation 注解
//获得类的名字
        String name = aClass1.getName();//包名+类名
        String simpleName = aClass1.getSimpleName();//类名

        //获得类的属性
        Field[] fields = aClass1.getFields();//获得public
        Field[] declaredFields = aClass1.getDeclaredFields();//可以获得所有包括private
        //重载,可以字段获取属性
        Field name1 = aClass1.getDeclaredField("name");
        System.out.println(name1);

        //获得类的方法
        Method[] methods = aClass1.getMethods();//获得本类和父类的public方法
        Method[] declaredMethods = aClass1.getDeclaredMethods();//获得本类所有方法
        //获得指定方法
        Method getName = aClass1.getMethod("getName",null);
        Method setName = aClass1.getMethod("setName", String.class);
        System.out.println(getName);

        //获得构造器
        Constructor[] constructors = aClass1.getConstructors();//空参
        Constructor constructor1 = aClass1.getConstructor(String.class, int.class, int.class);
        //获得指定的构造器
        Constructor constructor = aClass1.getConstructor();
        System.out.println(constructor);

        //构造一个对象
        User user1 = (User) aClass1.newInstance();//做一个强转,本质是调用类的无参构造
        System.out.println(user1);
        //通过构造器创建一个对象
        Constructor constructor2 = aClass1.getConstructor(String.class, int.class, int.class);
        User user2 = (User) constructor2.newInstance("bacon", 1, 25);//也是一个强转
        System.out.println(user2);
        //调用方法
        Method setName1 = aClass1.getMethod("setName", String.class);
        setName1.invoke(user2,"bacon2");//需要传入一个对象
        System.out.println(user2);
        //私有方法
        Method love = aClass1.getDeclaredMethod("love", null);
        love.setAccessible(true);//私有方法也需要设置权限
        love.invoke(user2);

        //操作属性
        //Field name2 = aClass1.getField("name");//私有字段获取不到
        Field name2 = aClass1.getDeclaredField("name");
        /*String name3 = name2.getName();//name
        System.out.println(name3);*/
        //私有字段通过getDeclaredField,但是字段操作必须通过类中方法啊,如果仍需要操作,可以设置安全检测
        name2.setAccessible(true);//默认是关闭的
        name2.set(user2,"bacon3");
        System.out.println(user2);

结果

private java.lang.String com.bacon.reflect.User.name
public java.lang.String com.bacon.reflect.User.getName()
public com.bacon.reflect.User()
user{name='null', id=0, age=0}
user{name='bacon', id=1, age=25}
user{name='bacon2', id=1, age=25}
love
user{name='bacon3', id=1, age=25}

  

不管private还是public,都会进行权限安全检测,而安全检测会降低程序执行效率,一般效率 new>反射(不安全检测)>反射(安全检测)

3.获取泛型信息

  • 基本类型
  • 引用类型
  • 泛型:一般都是list,map集合
public class TestReflect {
    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 ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        

        //获取泛型信息
        Method test01 = TestReflect.class.getMethod("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);
                }
            }
        }

        //获取泛型信息
        Method test02 = TestReflect.class.getMethod("test02",null);
        //得到泛型返回类型
        Type genericReturnType = test02.getGenericReturnType();
        System.out.println(genericReturnType);
        if(genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

    }
}

结果

#java.util.Map
class java.lang.String
class com.bacon.reflect.User
#java.util.List
class com.bacon.reflect.User
java.util.Map
class java.lang.String
class com.bacon.reflect.User

4.反射操作注解

//反射操作注解
        Annotation[] annotations = aClass1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        Table annotation = aClass1.getAnnotation(Table.class);
        System.out.println(annotation);
        String value = annotation.value();
        System.out.println(value);
        Field name3 = aClass1.getDeclaredField("name");
        Filed annotation1 = name3.getAnnotation(Filed.class);
        System.out.println(annotation1);
        String columnName = annotation1.columnName();
        String type = annotation1.type();
        System.out.println(columnName+"  "+type);

结果

@com.bacon.reflect.Table(value=db_user)
@com.bacon.reflect.Table(value=db_user)
db_user
@com.bacon.reflect.Filed(columnName=db_name, type=varchar)
db_name  varchar

 

你可能感兴趣的:(反射:Reflection)