Java反射(一)
来源:互联网 发布:知否之风的下一句 编辑:程序博客网 时间:2024/06/15 21:58
1.
Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能就称为Java语言的反射机制。动态获取类中的信息就是Java的反射机制。可以理解为对类的解剖。
2.
反射大大的提高了程序的扩展性。反射是程序为外部提供了接口和配置文件,通过对接口的实现和对配置文件的配置,程序通过反射会自动加载实现了接口的类,从而读取类中内容,实现程序的扩展。
3.
通过一个类的字节码文件获得该类的属性和方法。通过class文件对象去使用该文件中的成员变量,构造方法,成员对象要想这样使用,必须先得到class文件的对象,其实就是的到class类的对象 class类包括: 成员变量 构造方法 成员方法获取class文件对象的方式 A:object类的getClass() --Person p = new Person(); Class c = p.getClass(); B: 数据类型的静态属性class --Class c = Person.class;或 --Class c = int.class;或 --Class c = String.class; C: class类中的静态方法 --public static Class forName(String className) --括号内的部分写的是类的带包全路径,即使是在同一个包下也要写全路径,否则会报找不到异常 --Class c = Class.forName("com.qfxa.Person");
一般我们使用哪一种呢?
A:自己玩 可以任选一种,第二种比较方便
B: 开发 选第三种
因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。
4.通过反射获取构造方法并使用
通过反射获取构造方法并使用1)获取字节码文件对象 Class c = Class.forName("com.qfxa.Person");2)获取构造方法 public Constructor[] getConstructors(); --所有public的构造方法 --返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有**公共**构造方法。 Constructor[] cons = c.getConstructors(); //遍历获取的构造方法 for(Constructor con : cons){ System.out.println(con); }2)想获取所有的构造方法,可以用 public Constructor[] getDeclaredConstructors(); 这个方法,返回Constructor对象的一个数组,这些对象反映此Class对象表示的类声明的**所有**构造方法。 --Constructor[] cons = c.getDeclaredConstructors(); 想获取单个构造方法,可以用(但是只能获得public修饰的构造方法) public Constructor getConstructor(Class<?>...parameterTypes) --...代表可变参数,有参数也行没有参数也行 --因为构造方法的参数可能有很多个也可能没有,所以用可变参数来代替所有的参数。 --参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象。 --Constructor con = c.getConstructor(); //返回的是空参构造方法对象。 --Constructor con = c.getConstructor(String.class,int.class,String.class);//返回的是例子中的三参构造方法对象。 通过反射获取私有的构造方法 public Constructor getDeclaredConstructor(Class<?>...parameterTypes) --Constructor con = c.getDeclaredConstructor(String.class); --这样会获得私有的构造方法,但是不能访问,因为私有的构造方法在外界不能访问。 --con.setAccessible(true); --通过这样设置,值为true代表反射的对象在使用时应取消java语言访问检查,这时候就可以访问私有构造方法了。3)根据获取的构造方法创建新实例 --用的方法:public T newInstance(Object... initargs) --使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 --T代表泛型 --Object obj = con.newInstance(); --obj表示的是Person类的对象 --Object obj = con.newInstance("tom",12,"haha"); --表示是通过三参构造方法获得的新实例。
5.通过反射获取成员变量并使用
通过反射获取成员变量并使用 --获取所有成员 getFields.getDeclaredFields --获取单个成员 getFields.getDeclaredField --修改成员的值 set(Object obj,Object value) //将指定对象上此Field对象表示的字段设置成指定的新值。
import java.lang.reflect.Constructor;import java.lang.reflect.Field;//通过反射获取成员变量并使用public class ReflectDmeo { public static void main(String[] args) throws Exception { //获取字节码文件对象 Class c = Class.forName("com.qfxa.Person"); //获取所有的public成员变量 Field[] fields1 = c.getFields(); for(Field field : fields1){ System.out.println(field); } //获取所有的成员变量 Field[] fields = c.getDeclaredFields(); for(Field f : fields){ System.out.println(f); } //获取单个成员变量 //获取address并对其赋值 /** * Person p = new Person(); * p.address = "Beijing"; * System.out.println(p); */ Field addressField = c.getField("address"); //通过无参构造创建对象 Constructor constructor = c.getConstructor(); Object object = constructor.newInstance(); //System.out.println(object); //public void set(Object obj,Object value) //将指定对象变量上此Field对象表示的字段设置为指定的新值。 addressField.set(object, "beijing"); //给object对象的addressField字段设置值为北京 /** * 需求:通过反射获取成员变量并使用 * 1.获取类的字节码文件对象 * --Class c = Class.forName("com.qfxa.Person"); * 2.获取单个成员变量address * --Field addressField = c.getField("address"); * 3.通过无参构造创建对象(原因是给成员变量设置新值时需要指定是哪个对象,所以需要创建一个对象) * --Constructor constructor = c.getConstructor(); * --Object object = constructor.newInstance(); * 4.将指定对象变量上此Field对象表示的字段设置为指定的新值 * --addressField.set(object, "beijing"); */ //获取成员变量name并对其赋值 //Field nameField = c.getField("name"); --会报下面错误 //Exception in thread "main" java.lang.NoSuchFieldException: name //报错是因为name这个成员变量是私有的,所以要用另一个方法getDeclaredField Field nameField = c.getDeclaredField("name"); //Exception in thread "main" java.lang.IllegalAccessException: Class com.qfxa03.ReflectDmeo can not access a member of class com.qfxa.Person with modifiers "private" //还报错是因为获取的成员变量name是私有的,不能访问,所以要设置setAccessible为true nameField.setAccessible(true); //修改成员变量name的值 nameField.set(object, "linqingxia"); System.out.println(object); //获取成员变量age并赋值 //管他的,直接用getDeclaredField方法调用,以便于能获得私有的成员变量 Field ageField = c.getDeclaredField("age"); //同样,管他的,直接设置了取消java的访问检查,以便于能对私有成员变量进行访问 ageField.setAccessible(true); //设置新建的object对象的age为指定值 ageField.set(object, 10); System.out.println(object); }}
6.通过反射获取成员方法并使用
获取所有方法 --getMethods --getDeclaredMethods获取单个方法 --getMethod --getDeclaredMethod暴力访问 --method.setAccessible(true);
package com.qfxa04;import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class ReflectDemo { public static void main(String[] args) throws Exception{ //获取字节码文件 Class c = Class.forName("com.qfxa.Person"); //获取所有的方法 --Method[] methods = c.getMethods(); //--获取自己的和父亲的public方法 --Method[] methods = c.getDeclaredMethods(); //--获取自己的所有方法不包括父亲的 //获取单个方法并使用 /** * Person p = new Person(); * p.show(); */ //获得构造方法 Constructor con = c.getConstructor(); //根据构造方法创建对象 Object object = con.newInstance(); //要拿到public void show()方法 //获取单个方法需要用到这个方法 --public Method getMethod(String name,Class<?>...ParameterTypes) --第一个参数表示的参数名,第二个参数表示的是方法的参数的class类型 Method m1 = c.getMethod("show"); //public Object invoke(Object obj,Object... args) --返回的是object接收,第一个参数表示对象是谁,第二个参数表示调用该方法的参数 m1.invoke(object); //其本质是调用objec的m1方法 --因为show 方法没有返回值也没有参数,所以这样写。 //获得public void method(String s)这个方法 Method m2 = c.getMethod("method", String.class); m2.invoke(object, "hahaha"); //获取public String getString(String s,int i)这个方法 Method m3 = c.getMethod("getString", String.class, int.class); Object objString = m3.invoke(object, "haha", 10);或者 String string = (String)m3.invoke(object, "hahah", 10); --当你知道返回的具体是什么类型的时候可以直接强制转成对应类型,否则用object接收,因为object可以接收所有类型 System.out.println(objString); System.out.println(string); //获得private void function()这个方法 Method m4 = c.getDeclaredMethod("function"); m4.setAccessible(true); m4.invoke(object); }}
阅读全文
0 0
- java 反射(一)
- Java反射(一)
- JAVA反射(一)
- Java反射(一)
- java反射(一)
- Java的反射(一)
- Java 反射学习(一)
- Java反射机制(一)
- Java反射(一)Class
- java反射机制(一)
- Java 反射机制(一)
- Java反射总结(一)
- Java反射相关(一)
- java--类反射(一)
- java反射机制(一)
- JAVA反射机制(一)
- 关于java反射(一)
- Java反射机制(一)
- FEC and RTX
- 计算机基础
- 小迪教程——第二天
- 分治法找假币
- USB TO TTL (PL-2303)在Win8.1驱动无法识别问题解决
- Java反射(一)
- java中装饰者设计模式
- 线段树模板
- 草药的价值(01背包)
- 廖晓峰博客滴python总结
- 泛型编程与函数模板
- Python入门
- java学习笔记
- ios学习笔记6--plist文件生成与读取