1、反射是一开始并不知道实例化对象是什么,则就无法使用new关键字来创建对象,这时候,我们就通过JDK提供的API进行反射调用。反射是运行时才知道要操作的类是什么,并且在运行时获取类的完整构造,并调用对应的方法。
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。 Java反射机制主要提供了以下功能:
在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
Java 是一门面向对象的语言。在面向对象的世界里,万事万物皆对象,既然万事万物皆对象,那么我们的类是不是对象呢?我们写的每一个类都可以看成一个对象,是 java.lang.Class 类的对象。每一个类对应的Class放在哪里呢?当我们写完一个类的Java文件,编译成class文件的时候,编译器都会将这个类的对应的class对象放在class文件的末尾。里面可以理解保存了类的元数据信息,一个类的元数据信息包括有属性,方法,构造器,实现了接口等等,那么这些信息在Java里都有对应的类来表示。
2、Class 类
Class是一个类,封装了当前对象所对应的类的信息

3、类加载器、构造器、Method、Field
举例说明
//先创建一个Person 类
public class Person {
String name;
private int age;
//包含一个带参的构造器和一个不带参的构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("我是两个参构造方法");
}
public Person() {
System.out.println("我是无参构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("This is setName");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
System.out.println("This is setAge");
}
//私有方法
private void privateMethod(){
System.out.println("This is private method");
}
}
//测试类
public class Test{
/*类加载器相关*/
public static void testClassLoader() throws ClassNotFoundException {
//1. 获取一个系统的类加载器(可以获取,当前这个类PeflectTest就是它加载的)
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
System.out.println("系统的类加载器 "+classLoader);
//2. 获取系统类加载器的父类加载器(扩展类加载器,可以获取).
classLoader = classLoader.getParent();
System.out.println("系统类加载器的父类加载器 "+classLoader);
//3. 获取扩展类加载器的父类加载器(引导类加载器,不可获取).
classLoader = classLoader.getParent();
System.out.println("扩展类加载器的父类加载器 "+classLoader);
//4. 测试当前类由哪个类加载器进行加载(系统类加载器):
Class<?> clazz = Class.forName("JavaGaoji.RefectFs.more.MyTestClassLoader");
classLoader = clazz.getClassLoader();
System.out.println("类加载器进行加载 "+classLoader);
//5. 测试 JDK 提供的 Object 类由哪个类加载器负责加载(引导类)
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println("Object 类由哪个类加载器 " +classLoader );
}
/*构造器相关*/
public static void testConstructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1、获取类;
String className = "Refect.Person"; //类的全路径名称
// Class<?> personClass = Class.forName(className);
Class<Person> personClass = (Class<Person>) Class.forName(className);
//获取所有构造方法
Constructor<Person>[] constructors = (Constructor<Person>[]) personClass.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("构造方法"+i+" " + constructors[i]);
}
//具体获取构造方法
//获取无参构造方法
Constructor<Person> constructor = personClass.getConstructor();
Object instance = constructor.newInstance();
//获取有参构造方法
Constructor<Person> constructor1 = personClass.getConstructor(String.class, int.class);
Person niko = constructor1.newInstance("Niko", 18);
niko.setName("小明");
}
/*字段相关*/
public static void testField() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
String className = "Refect.Person";
//获取类
Class<Person> personClass = (Class<Person>) Class.forName(className);
//获取类中的所有字段
System.out.println("获取类中的所有字段包括私有字段,不包括父类的字段");
Field[] fields = personClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
System.out.println(field.getName());
}
System.out.println("==============");
//获取之指定字段
System.out.println("获取之指定字段");
Field name = personClass.getDeclaredField("name");
//给字段赋值
System.out.println("给字段赋值");
//获取对象
Person person = personClass.newInstance();
name.set(person,"Niko");
System.out.println(person.getName());
System.out.println("==============");
//获取私有字段并赋值
System.out.println("获取私有字段并赋值");
Field age = personClass.getDeclaredField("age");
age.setAccessible(true);
age.set(person,18);
System.out.println(person.getAge());
}
/*方法相关*/
public static void testMethod() throws ClassNotFoundException,
NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
String className = "Refect.Person";
//获取类
Class<Person> personClass = (Class<Person>) Class.forName(className);
//获取类中的所有方法,包括父类的方法, 不能获取私有的方法
System.out.println("获取类中的所有方法,包括父类的方法, 不能获取私有的方法");
Method[] methods = personClass.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
System.out.println("类中的方法"+i +" "+ method.getName());
}
//获取类中所有的方法,且只获取当前类的方法, 包括自身的私有方法
System.out.println("获取类中所有的方法,且只获取当前类的方法, 包括自身的私有方法");
Method[] declaredMethods = personClass.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
Method method = declaredMethods[i];
System.out.println("类中的方法"+method);
// Class<?>[] parameterTypes = method.getParameterTypes();
// for (int j = 0; j < parameterTypes.length; j++) {
// System.out.println("类中的方法"+method.getName() +" 参数 "+ parameterTypes[j]);
// }
}
//第一个参数是方法名字 第二个参数是参数类型
System.out.println("==================");
Method method = personClass.getMethod("setName", String.class);
System.out.println(method);
//调用公共方法
Person person = personClass.newInstance();
//第一个参数为对象 后面是该方法的参数
method.invoke(person,"Hello world");
//调用私有方法
Method privateMethod = personClass.getDeclaredMethod("privateMethod");
//调用私有方法必须先调用此方法,传入 true
privateMethod.setAccessible(true);
privateMethod.invoke(person);
}
public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException {
// Test.testClassLoader();
// Test.testConstrucTor();
// Test.testMethod();
Test.testField();
}
}