关于反射

1. 三种获取类对象的方式

三种获取类对象的方式,内存中一个类只会有一个class对象。

    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射来获取对象的方式,包名+类名
        //内存中一个类只会有一个class对象
        Class s1 = Class.forName("study.TestSort");
        Class s2 = TestSort.class;
        TestSort testSort = new TestSort();
        Class s3 = testSort.getClass();

        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
    }

2.哪些类有Class 对象?

  • class
  • 接口
  • []数组
  • enum 枚举
  • annotation 注解
  • 基本数据类型
  • void

3. 类的执行顺序:

首先是类的内容:静态变量、静态初始化块
再是 实例内容:变量、初始化块、构造器

4.什么时候会发生类的初始化?

类分为主动引用和被动引用。主动引用会发生类的初始化,被动引用不会。
被动引用

//引用类的常量不会发生初始化,常量通常在链接阶段就存入调用类的常量池中了
public class ReflectTest {
    static {
        System.out.println("Main类被加载");
    }

    public static void main(String[] args) {
        System.out.println(Son.M);
    }
}

class Father{
    static int b = 2;
    static {
        System.out.println("父类被加载");
    }
}

class Son extends Father{
    static {
        System.out.println("子类被加载");
        m = 300;
    }
    static int m = 100;
    static final int M = 1;
}

输出
Main类被加载
1

M被final修饰,不需要去初始化,在链接阶段就存在了。

需要初始化的时候:
当虚拟机启动,会先初始化main方法所在的类。
当new一个对象时。
调用类的静态成员(除了final)和静态方法也会初始化。
对类进行反射调用。

 public static void main(String[] args) {
        System.out.println(Son.m);
    }

前面例子里,打印这个
输出
Main类被加载
父类被加载
子类被加载
100

5.通过反射获取类的参数

public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c1 = User.class;
        //调用无参构造函数
        //User user = (User) c1.newInstance();
        //用构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor();
        User user = (User) constructor.newInstance();
        //获取setName方法,如果setname方法是private,是无法invoke的,必须要setAccessible(true)
        Method setNameMethod = c1.getDeclaredMethod("setName", String.class);
        setNameMethod.setAccessible(true);
        setNameMethod.invoke(user,"mmm");
        System.out.println(user.getName());
    }

对象关系映射

ORM 对象和表结构对象

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class s1 = Class.forName("reflect.Student");
        //通过反射获得value的值
        Table table = (Table) s1.getAnnotation(Table.class);
        String value = table.value();
        System.out.println(value);

        java.lang.reflect.Field field = s1.getDeclaredField("name");
        Field fieldAnnotation = field.getAnnotation(Field.class);
        System.out.println(fieldAnnotation.columnName());
    }
}

@Table("db_student")
class Student{
    @Field(columnName = "name", type = "varchar")
    private String name;
    @Field(columnName = "type", type = "int")
    private int age;
}

//放在class上
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field{
    String columnName();
    String type();
}

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