反射-------笔记

Java反射-------笔记

1. 静态语言 动态语言
  1. 动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。例如js的var类型
  2. 静态语言与动态语言相对,运行时结构不可变的语言 Java

Java不是动态语言,但是可以通过反射机制获得类似于动态语言的特性。

2. 反射 Java Reflection

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

3.反射的功能
  1. 在运行时判断对象所属的类
  2. 在运行时构造类的对象
  3. 在运行时获得类所具有的成员变量和方法
  4. 在运行时获取泛型信息
  5. 在运行时调用任意一个对象的成员变量和方法
  6. 在运行时处理注解
  7. 生成动态代理
4. Class类
1. Class本身也是一个类
2. Class对象只能由系统建立
3. 一个加载的类在 JVM 中只会有一个Class实例
4. 一个Class对象对应的是一个加载到JVM中的一个class文件
5. 每个类的实例都会记得自己是由哪个Class实例所产生
6. 通过Class可以完整的得到一个类中的所有被加载的结构
7. Class类是Reflection的根源,只有先获得相应的Class对象才能动态加载类
public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        //一个类内存中只有一个class对象
        Class<?> aClass = Class.forName("test.User");
        Class<?> bClass = Class.forName("test.User");
        System.out.println(aClass==bClass);
    }
}
class User{
    
    
    private String name;
    private int id;
    private int age;
    public User(){
    
    
    }
    public User(String name, int id, int age) {
    
    
        this.name = name;
        this.id = id;
        this.age = age;
    }
	//getter 和 setter方法
    @Override
    public String toString() {
    
    
        return "Reflection{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Person person = new Student();
        Class c1 = Student.class;
        Class c2 = person.getClass();
        Class c3 = Class.forName("test.Student");
        System.out.println(c1.hashCode());
        System.out.println(c1.hashCode());
        System.out.println(c1.hashCode());
    }
}
class Person{
    
    
    String name;
    public Person(){
    
    
    }
    //getter 和 setter方法
    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}
class Student extends Person{
    
    
    public Student(){
    
    
        this.name = "student";
    }
}
929338653
929338653
929338653

所有类型的Class

public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Class c1 = Object.class;//类
        Class c2 = Comparable.class;//接口
        Class c3 = String[].class;//数组
        Class c4 = int[][].class;//二维数组
        Class c5 = Override.class;//注解
        Class c6 = ElementType.class;//枚举类型
        Class c7 = void.class;//空
        Class c8 = Integer.class;//基本数据类型
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
    }
}
//控制台打印
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
void
class java.lang.Integer

Test

public class Test {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        A a = new A();
        System.out.println(A.m);
    }
}
class A{
    
    
    static{
    
    
        System.out.println("A静态代码块初始化");
        m = 300;
    }
    static int m = 100;
    public A() {
    
    
        System.out.println("A对象初始化");
    }
}
A静态代码块初始化
A对象初始化
100
public class Test {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        System.out.println(B.q);
        //System.out.println(B.m);
    }
}
class A{
    
    
    static{
    
    
        System.out.println("A静态代码块初始化");
    }
    static final int m = 100;
    public A() {
    
    
        System.out.println("A对象初始化");
    }
}
class B extends A{
    
    
    static {
    
    
        System.out.println("B静态代码块初始化");
    }
    static int q = 200;
}
//调用B.m会初始化父类和子类
A静态代码块初始化
B静态代码块初始化
200
//m在常量池中 不会对类进行初始化 100
5. 类加载器
public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);
        //获得系统类加载器的父类加载器-->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);
        //获得扩展类加载器-->根加载器
        ClassLoader pparent = parent.getParent();
        System.out.println(pparent);
        //获得当前类加载器
        ClassLoader current = Class.forName("test.Reflection").getClassLoader();
        System.out.println(current);
        //测试JDK内置的类
        ClassLoader root = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(root);
        //获得系统类加载器可以加载的路径
        //String property = System.getProperty("java.class.path");
        //System.out.println(property);
        
    }
}
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@3764951d
//根类加载器用C/C++编写不可直接获取
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null
6. 通过反射获取类的信息
public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Class name = Class.forName("test.User");
        //获得类的名字
        System.out.println(name.getName());
        //获得类的简单名字
        System.out.println(name.getSimpleName());
        //获得类的全部属性 getFields 获得公有属性
        Field[] strings = name.getDeclaredFields();
        for(Field temp : strings){
    
    
            System.out.println(temp);
        }
        //获得本类及其父类的公有方法
        Method[] methods = name.getDeclaredMethods();
        for(Method temp : methods){
    
    
            System.out.println(temp);
        }
        //获得本类的所有方法
        Method[] declaredMethods = name.getDeclaredMethods();
        for(Method temp : declaredMethods){
    
    
            System.out.println("Declare:   "+temp);
        }
    }
}

class User{
    
    
    private String name;
    private int id;
    private int age;
    public User(){
    
    
    }
    public User(String name, int id, int age) {
    
    
        this.name = name;
        this.id = id;
        this.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;
    }
    @Override
    public String toString() {
    
    
        return "Reflection{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

7. 通过反射创建对象
public class Reflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    
    
        //获得class对象
        Class c1 = Class.forName("test.User");
        //通过反射构造对象 调用类的无参构造
        User o = (User) c1.newInstance();
        System.out.println(o);
        //通过构造器创建对象
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User qwe =(User) declaredConstructor.newInstance("qwe", 1, 2);
        System.out.println(qwe);
        //通过反射调用方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        User o1 = (User) c1.newInstance();
        //invoke 激活方法,传入对象和参数
        setName.invoke(o1,"qwe");
        System.out.println(o1.getName());
        //通过反射操作属性
        User o2 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //name是私有属性 不能获取对象的私有属性 先关闭程序的安全监测
        name.setAccessible(true);
        name.set(o2,"wl");
        System.out.println(o2.getName());
    }
}
Reflection{
    
    name='null', id=0, age=0}
Reflection{
    
    name='qwe', id=1, age=2}
qwe
wl

Process finished with exit code 0
8.反射性能对比
public static void main(String[] args){
    
    
        test();
        test1();
        test2();
}
    public static void test(){
    
    
        User user = new User();
        long start = System.currentTimeMillis();
        for(int i=0;i<1000000000;i++){
    
    
            user.getName();
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
    public static void test1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        User user = new User();
        Class c1 = user.getClass();
        Method method = c1.getDeclaredMethod("getName",null);
        long start = System.currentTimeMillis();
        for(int i=0;i<1000000000;i++){
    
    
            method.invoke(user,null);
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
    public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        User user = new User();
        Class c1 = user.getClass();
        Method method = c1.getDeclaredMethod("getName",null);
        method.setAccessible(true);
        long start = System.currentTimeMillis();
        for(int i=0;i<1000000000;i++){
    
    
            method.invoke(user,null);
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
3
1580
1062

Process finished with exit code 0
9.获取泛型信息
public class Reflection {
    
    
    public static void main(String[] args) throws NoSuchMethodException {
    
    
        Method test1 = Reflection.class.getDeclaredMethod("test1", Map.class, List.class);
        Type[] genericParameterTypes = test1.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 test2 = Reflection.class.getDeclaredMethod("test2");
        Type genericReturnType = test2.getGenericReturnType();
        System.out.println(genericReturnType);
        if(genericReturnType instanceof ParameterizedType){
    
    
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
    
    
                System.out.println(actualTypeArgument);
            }
        }

    }

    public void test1(Map<String,User> map, List<User> list){
    
    
        System.out.println("test1");
    }

    public Map<String,User> test2(){
    
    
        System.out.println("test2");
        return null;
    }
}

10. 通过反射获取注解信息
public class Reflection {
    
    
    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
    
    

        Class<?> aClass = Class.forName("test.User");
        //通过反射获得注解
        Annotation[] annotation = aClass.getAnnotations();
        for (Annotation temp : annotation) {
    
    
            System.out.println(temp);
        }
        //获得注解的value值
        Table table = (Table)aClass.getAnnotation(Table.class);
        String value = table.value();
        System.out.println(value);
        //获得类指定注解
        Field f = aClass.getDeclaredField("name");
        FieldT annotations = f.getAnnotation(FieldT.class);
        System.out.println(annotations.columnName());
        System.out.println(annotations.type());
        System.out.println(annotations.length());
    }


}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    
    
    String value();
}

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

@Table("user")
class User{
    
    
    @FieldT(columnName = "name",type = "varchar",length = 3)
    private String name;
    @FieldT(columnName = "id",type = "int",length = 10)
    private int id;
    @FieldT(columnName = "age",type = "int",length = 10)
    private int age;
    public User(){
    
    
    }
    public User(String name, int id, int age) {
    
    
        this.name = name;
        this.id = id;
        this.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;
    }
    @Override
    public String toString() {
    
    
        return "Reflection{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41454682/article/details/112261284