反射【Reflection】

92 阅读4分钟

概念

  1. 反射是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
  2. 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们通过这个对象看到类的结构。

代码演示:

package ReflectionStudy;

//什么是反射
public class demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获取类的Class对象
        Class c1 = Class.forName("ReflectionStudy.user");
        System.out.println(c1);//class ReflectionStudy.user

        //一个类中在内存中只有一个Class对象
        //一个类被加载后,类的整个结构都会被封装在Class对象中
        Class c2 = Class.forName("ReflectionStudy.user");
        Class c3 = Class.forName("ReflectionStudy.user");
        Class c4 = Class.forName("ReflectionStudy.user");
        Class c5 = Class.forName("ReflectionStudy.user");

        System.out.println(c2.hashCode());//460141958
        System.out.println(c3.hashCode());//460141958
        System.out.println(c4.hashCode());//460141958
        System.out.println(c5.hashCode());//460141958
    }
}

//实体类
class user{
    private String name;
    private int age;
    private int id;

    public user() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
  1. 正常方式与反射方式的对比:

Class类

  1. 获得class对象的方法:
package ReflectionStudy;

//获得class对象
public class demo02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人是:"+person.name);//这个人是:学生

        //方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());//460141958

        //方式二:通过forname获得
        Class c2 = Class.forName("ReflectionStudy.Student");
        System.out.println(c2.hashCode());//460141958

        //方式三:通过 类名.class 获得
        Class c3 = Student.class;
        System.out.println(c3);//class ReflectionStudy.Student

        //方式四  基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);//int

        //获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);//class ReflectionStudy.Person

    }
}

class Person{
    public String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student extends Person{
    public Student() {
        this.name="学生";
    }
}

class Teacher extends Person{
    public Teacher() {
        this.name="老师";
    }
}
  1. 所有类型的class
package ReflectionStudy;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;

//所有类型的class
public class demo03 {

    public static void main(String[] args) {
        Class c1 = Object.class;//类
        Class c2 = Comparable.class;//接口
        Class c3 = String[].class;//一维数组
        Class c4 = int[][].class;//二维数组
        Class c5 = Annotation.class;//注解
        Class c6 = ElementType.class;//枚举
        Class c7 = Integer.class;//基本数据类型
        Class c8 = void.class;//void
        Class c9 = Class.class;//Class

        System.out.println(c1);//class java.lang.Object
        System.out.println(c2);//interface java.lang.Comparable
        System.out.println(c3);//class [Ljava.lang.String;
        System.out.println(c4);//class [[I
        System.out.println(c5);//interface java.lang.annotation.Annotation
        System.out.println(c6);//class java.lang.annotation.ElementType
        System.out.println(c7);//class java.lang.Integer
        System.out.println(c8);//void
        System.out.println(c9);//class java.lang.Class

        //只要元素的类型与维度一样,就是同一个Class
        int[] a = new int[5];
        int[] b = new int[50];
        System.out.println(a.getClass().hashCode());//460141958
        System.out.println(b.getClass().hashCode());//460141958
    }

}
  1. Java的内存分析:

代码演示

package ReflectionStudy;

public class demo04 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
    }
}

class A{

    static {
        System.out.println("静态代码块");
        m = 30;
    }
    static int m = 100;
    public A() {
        System.out.println("无参构造");
    }
}

代码运行结果:

  1. 获得类的运行时结构

直接代码演示:

package ReflectionStudy;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//获得类的运行时结构
public class demo05 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c = Class.forName("ReflectionStudy.user");

        System.out.println("=============获得类的名字==================");

        System.out.println("getName()方法获得的类名:" + c.getName());
        System.out.println("getSimpleName()方法获得的类名:" + c.getSimpleName());

        System.out.println("=============获得类的属性==================");
        Field[] fields = c.getFields();//只能获得本类的public属性
        for (Field field : fields) {
            System.out.println("getFields()方法获得的属性:" + fields);
        }
        fields = c.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("getDeclaredFields()方法获得的属性:" + fields);
        }

        System.out.println("=============获得类的指定属性===============");
        Field field = c.getDeclaredField("name");
        System.out.println("获得类的指定属性" + field);

        System.out.println("=============获得类的方法==================");
        Method[] methods = c.getMethods();//找到本类及父类的全部public方法
        for (Method method : methods) {
            System.out.println("getMethods()方法获得的方法:" + method);
        }
        methods = c.getDeclaredMethods();//找到本类的所有方法
        for (Method method : methods) {
            System.out.println("getDeclaredMethods()方法获得的方法:" + method);
        }

        System.out.println("=============获得类的指定方法===============");
        Method method = null;

        method = c.getDeclaredMethod("getName", null);
        System.out.println(method);
        method = c.getDeclaredMethod("setName", String.class);
        System.out.println(method);

        System.out.println("=============获得构造器====================");
        Constructor[] constructors = c.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getConstructors()获得的构造器:"+constructor);
        }

        constructors = c.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getDeclaredConstructors()获得的构造器:"+constructor);
        }

        System.out.println("=============获得指定的构造器===============");
        Constructor declaredConstructor = c.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println("获得指定的构造器:"+declaredConstructor);
    }

}

运行结果:

=============获得类的名字==================
getName()方法获得的类名:ReflectionStudy.user
getSimpleName()方法获得的类名:user
=============获得类的属性==================
getDeclaredFields()方法获得的属性:[Ljava.lang.reflect.Field;@74a14482
getDeclaredFields()方法获得的属性:[Ljava.lang.reflect.Field;@74a14482
getDeclaredFields()方法获得的属性:[Ljava.lang.reflect.Field;@74a14482
=============获得类的指定属性===============
获得类的指定属性private java.lang.String ReflectionStudy.user.name
=============获得类的方法==================
getMethods()方法获得的方法:public java.lang.String ReflectionStudy.user.getName()
getMethods()方法获得的方法:public int ReflectionStudy.user.getId()
getMethods()方法获得的方法:public void ReflectionStudy.user.setName(java.lang.String)
getMethods()方法获得的方法:public void ReflectionStudy.user.setId(int)
getMethods()方法获得的方法:public int ReflectionStudy.user.getAge()
getMethods()方法获得的方法:public void ReflectionStudy.user.setAge(int)
getMethods()方法获得的方法:public final void java.lang.Object.wait() throws java.lang.InterruptedException
getMethods()方法获得的方法:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
getMethods()方法获得的方法:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getMethods()方法获得的方法:public boolean java.lang.Object.equals(java.lang.Object)
getMethods()方法获得的方法:public java.lang.String java.lang.Object.toString()
getMethods()方法获得的方法:public native int java.lang.Object.hashCode()
getMethods()方法获得的方法:public final native java.lang.Class java.lang.Object.getClass()
getMethods()方法获得的方法:public final native void java.lang.Object.notify()
getMethods()方法获得的方法:public final native void java.lang.Object.notifyAll()
getDeclaredMethods()方法获得的方法:public java.lang.String ReflectionStudy.user.getName()
getDeclaredMethods()方法获得的方法:public int ReflectionStudy.user.getId()
getDeclaredMethods()方法获得的方法:public void ReflectionStudy.user.setName(java.lang.String)
getDeclaredMethods()方法获得的方法:public void ReflectionStudy.user.setId(int)
getDeclaredMethods()方法获得的方法:public int ReflectionStudy.user.getAge()
getDeclaredMethods()方法获得的方法:public void ReflectionStudy.user.setAge(int)
=============获得类的指定方法===============
public java.lang.String ReflectionStudy.user.getName()
public void ReflectionStudy.user.setName(java.lang.String)
=============获得构造器====================
getConstructors()获得的构造器:public ReflectionStudy.user()
getConstructors()获得的构造器:public ReflectionStudy.user(java.lang.String,int,int)
getDeclaredConstructors()获得的构造器:public ReflectionStudy.user()
getDeclaredConstructors()获得的构造器:public ReflectionStudy.user(java.lang.String,int,int)
=============获得指定的构造器===============
获得指定的构造器:public ReflectionStudy.user(java.lang.String,int,int)