package com.test2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 作者:******
* 功能:反射相关知识的复习(在注释中简单表明核心作用,供遗忘后复习使用)
*/
public class ReflectTest
{
public static void main(String args[]) throws Exception
{
//反射的基础,Class类,可以理解为java语言抽象出的封装类 的 类
//Class类作为类的类,自然包含的就是在封装类层面的关于类本身的内容信息
//获取Class类的三种常用方法
//① 类自身包含的隐藏的静态成员变量
Class c1 = ReflectTest.class;
//② 根据一个具体的类实例的一个成员方法
ReflectTest reflectTest = new ReflectTest();
Class c2 = reflectTest.getClass();
//③ 根据类的全限定名加载(注意该方法会抛出异常)
Class c3 = Class.forName("com.test2.ReflectTest");
//打印一下测试信息
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
//ps:一个细节思考
//java的动态绑定特性对获取类的Class信息有什么影响?
//结论,获取Class的时候,无关乎引用,只关心具体的绑定对象所属的类型
Object object = new ReflectTest();
Class z4 = object.getClass();
System.out.println(z4);
//根据一个类的各种方法获取到一个类的Class后
//还可以反过来,利用Class获取到一个类的具体实例对象
//这个过程也会有两种方法
//① 直接调用现成的API方法(注意该方法要求类中必须有无参的构造方法)
ReflectTest reflectTest1 = (ReflectTest) z4.newInstance();
//② 如果想要newInstance有参构造方法的类,则先得到构造器(这其实涉及到了反射,下面详解)
ReflectTest reflectTest2 = (ReflectTest)
z4.getDeclaredConstructor(int.class, String.class).
newInstance(100, "liu");
//有了Class,就有了封装抽象类的类信息,然后就可以获取了(反射的表现)
//可以通过反射获取类中的信息,包括三类,成员变量,成员方法,构造方法
//1. 获取成员方法
//① 已知方法名字
Method method = c1.getMethod("getId");
method.invoke(reflectTest1); //可以手动执行
//② 获取所有成员方法(该方法不会获取当前类继承自其它类的方法)
//这里有个细节问题,就是该方法可以获取其类内部私有的成员方法
Method[] methods = c1.getDeclaredMethods();
for(Method temp : methods)
{
String methodName = temp.getName();
System.out.println(methodName);
}
//③ 获取所有成员方法(该方法不会获取私有的成员方法)
//但是可以获取继承自上层父类的成员方法
Method[] methodss = c1.getMethods();
//2. 获取成员变量
//java反射机制获取成员变量是保存在java.lang.Reflect.Filed中的
//① 已知成员变量的名字(注意变量不可为私有的)
Field field = c1.getField("flag");
String fieldType = field.getType().toString();
System.out.println(fieldType);
System.out.println(field.get(reflectTest1));
//② 获取所有的成员变量(该方法不会获取当前类继承自上层的成员变量)
//类似于之前,该方法可以获取私有成员变量
Field[] fields = c1.getDeclaredFields();
for(Field temp : fields)
{
String fieldName = temp.getName();
System.out.println(fieldName);
}
//③ 获取所有成员变量(该方法不会获取私有的成员变量)
//但是该方法可以获取继承自上层父类的成员变量
Field[] fieldss = c1.getFields();
for(Field temp : fields)
{
String fieldName = temp.getName();
System.out.println(fieldName);
}
//3. 获取构造方法
//java反射机制获取的构造方法是放在Constructor中的
//① 无参的构造方法
Constructor constructor = c1.getDeclaredConstructor();
ReflectTest rrr = (ReflectTest) constructor.newInstance();
//② 有参数的构造方法
Constructor constructor1 = c1.getDeclaredConstructor(int.class, String.class);
ReflectTest eee = (ReflectTest) constructor1.newInstance(100, "jie");
System.out.println(rrr == eee);
}
//这是一个封装类中的抽象信息
private int id = 0;
private String name = null;
public boolean flag = true;
public ReflectTest()
{
}
public ReflectTest(int id, String name)
{
this.id = id;
this.name = name;
}
public void method1(int id)
{
}
private void method2(String name)
{
}
public int getId()
{
System.out.println("进入到了getId方法!");
return this.id;
}
}
测试程序的简单运行结果: