反射介绍
-
反射是发生在程序运行期间的行为
-
在以后的框架或技术的底层大量使用到了反射技术,使用代码变得更灵活,更简单
*/ -
反射:
-
1.创建对象这个类型的Class对象的一个镜像|复制体
-
2.类加载到内存的时候,就在内存中存在的,不用我们手动创建就已经存在,并且只一个类只有一个表示这个类的Class对象
-
3.你能拿到一个类型的Class对象,能够使用Class类中的这些成员方法操作这个类型
-
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。
-
Java 反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。
获取类的 class 对象,也有三种方式:
①Class.forName(”包名.类名”)//一般尽量采用该形式
②类.class
③对象.getClass()
Class c1 = Class.forName("class0719.Student"); // class.forName(包名.类名)
Class c2 =Student.class; // 类名.class
Class c3 =new Student().getClass(); // 对象.getClass
System.out.println(c1==c2);
System.out.println(c1==c3);
System.out.println(c1);
运行结果
true
true
class class0719.Student
推荐使用第一种方式-----------划重点
一些方法
直接上代码
String s=c1.getName(); // getName() 获取该类的名字
System.out.println(s);
System.out.println(c1.toString()); // 字符串的方式输出该类的名字
System.out.println("============");
System.out.println(Arrays.toString(c1.getClasses())); // getClasses()获取该类以及他父类的所有公共的内部类
System.out.println(Arrays.toString(c1.getInterfaces())); //getInterfaces() 确定此对象所表示的类或接口实现的接口。
System.out.println(c1.getModifiers()); // getModifiers()返回此类或接口以整数编码的 Java 语言修饰符
System.out.println(Modifier.toString(c1.getModifiers())); // Modifier.toString 将该类返回的语言修饰符转换成字符串形式
System.out.println("============");
结果
class0719.Student
class class0719.Student
============
[class class0719.Student$ZZZ]
[interface class0719.StudentStudy]
1
public
一些应用
用来操作普通方法
- Method getMethod(String name, Class<?>… parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods() - Method getDeclaredMethod(String name, Class<?>… parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods()
执行方法
Object invoke(Object obj, Object… args) 参数1:调用方法的对象 参数2:方法的实参 返回值:执行方法的返回值
*/
下面直接上代码
Method[] arr=cls.getMethods(); // 返回一个 Method返回一个数组,其中包含 它反映此 Class 对象所表示的类或接口的指定公共成员方法。
cls.newInstance(); // 创建一个新的这个 类对象所表示的类的实例。
System.out.println(Arrays.toString(arr)); //
System.out.println("============");
// 获取某个指定的方法
@SuppressWarnings("unchecked")
///getDeclaredMethod(方法名,参数的数据类型的Class对象列表)
Method method1 = cls.getDeclaredMethod("Studya",String.class); // 返回一个 方法指定对象,反映了声明的方法这个 类对象所表示的类或接口。
Student cs=(Student) cls.newInstance(); //创建一个新的这个 类对象所表示的类的实例。 类被实例化,好像 new表达式用一个空参数列表。
method1.invoke(cs, "吴亦凡"); //调用底层方法由这个 方法对象,指定对象的指定参数 obj——调用对象的方法 args——用于方法调用的参数
System.out.println("============");
//获取私有的方法
Method method2=cls.getDeclaredMethod("play",String.class);
Student cs1=(Student) cls.newInstance();//创建一个新的这个 类对象所表示的类的实例。 类被实例化,好像 new表达式用一个空参数列表。
//setAccessible() // 设置这个方法的访问类型
method2.setAccessible(true); // 为这个对象设置 accessible标志指定的布尔值。值 true表明反射的对象应该抑制Java语言访问检查时使用。值 false表明反射的对象应执行Java语言访问检查。
method2.invoke(cs1, "蔡徐坤");
上结果
============
吴亦凡努力rap
============
蔡徐坤打篮球
获取构造方法
- 1.获取
一个类型的构造器 - Constructor getConstructor(Class<?>… parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors() 返回所有的公共的构造器
通过构造器创建对象
1.Class类中newInstance() 创建对象–>空构造
2.Constructor类的成员方法 T newInstance(Object… initargs) ,接收匹配构造器的实参创建一个对象
3.Constructor getDeclaredConstructor(Class<?>… parameterTypes 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
4.Constructor<?>[] getDeclaredConstructors() 获取所有的构造器对象,包括私有的
*/
还是上代码
public static void testConstructor(Class cls) throws Exception{
Student cs=(Student) cls.newInstance();
System.out.println(cs);
System.out.println("============");
公共的 带参构造 返回一个 Constructor指定对象,反映了公共类的构造函数由这个 类对象表示。 parameterTypes——参数数组
// 结果 ---公众的 Constructor对象 parameterTypes指定匹配的构造函数
Constructor con = cls.getConstructor(String.class,int.class,boolean.class);
//con表示匹配的构造方法
Student st=(Student) con.newInstance("杨幂",19,true); //通过指定构造器公共的创建对象
System.out.println(st);
System.out.println("============");
//Constructor<?>[] getConstructors() 返回所有的公共的构造器
Constructor[] con1 = cls.getConstructors();
System.out.println(Arrays.toString(con1));
System.out.println("============");
Student st1=(Student) con1[0].newInstance("宋慧乔",23,true); //通过指定构造器公共的创建对象
System.out.println(st1);
System.out.println("============");
//Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes
//返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor con2 = cls.getDeclaredConstructor(String.class);
//为这个对象设置 accessible标志指定的布尔值。值 true表明反射的对象应该抑制Java语言访问检查时使用。值 false表明反射的对象应执行Java语言访问检查。 //
//为这个对象访问权限
con2.setAccessible(true);
Student st2=(Student) con2.newInstance("呵呵哒");
System.out.println(st2);
con2.setAccessible(false);
System.out.println("============");
还是上结果
Student [name=null, age=0, sex=false]
============
Student [name=杨幂,/ age=19, sex=true]
============
[public class0719.Student(java.lang.String,int,boolean), public class0719.Student()]
============
Student [name=宋慧乔, age=23, sex=true]
============
Student [name=呵呵哒, age=0, sex=false]
============
利用反射创建对象与new对象稍有不同
1.反射会先拿到Student的“类对象”,然后通过类对象获取“构造器对象”再通过构造器对象创建一个对象,具体步骤:
Class cls = Class.fromName("class0719.Student"); // 获取类对象
Constructor con = cls.getConstructor(形参.class); // 获取构造器对象
Student st =(这里需要强制类型转换)con.newInstance(实参);
// 获取字段
Field f1= cls.getDeclaredField("name");
System.out.println(st2.name);
结果当然是:呵呵哒
2019.07.19