java基础学习之反射 十六

来源:互联网 发布:淘宝店铺介绍在哪里看 编辑:程序博客网 时间:2024/06/10 07:41
反射是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都只能都调用它的任意一个
方法和属性,这种动态获取的信息一级动态调用对象的方法的功能呢个称为java 的反射机制。



反射其实就是动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,
并将字节码文件中的内容都封装成对象,这样便于操作这些成员。就是把JAVA类中的各种成分反射成为相应的JAVA类
简单说:反射技术可以对一个类进行解剖。


如果想要对指定名称的字节码文件进行加载


反射的好处:大大的增强了程序的扩展性。 
反射的基本步骤: 
1、获得Class对象,就是获取到指定的名称的字节码文件对象。 
2、实例化对象,获得类的属性、方法或构造函数。 
3、访问属性、调用方法、调用构造函数创建对象。


得到类的字节码文件相同,这三种方式。
1.Class cls1=类名.class 相对简单,还是需要明确类名
2.cls1.getclass();必须要明确具体的类,并创建对象

3.class.forName("完整的类名(带包名)");



person类

package fanshe;public class person {public String name;private int age;public person() {// TODO Auto-generated constructor stub}private person(String name){this.name = name;}public person(String name, int age) {this.name = name;this.age = age;}public void show(){System.out.println("show");}public void function(String s){System.out.println("function"+s);}public String returnValue(String name, int age){return"hello"+name+"**********"+age;}private void hello(){System.out.println("helloworld");}@Overridepublic String toString() {return "person [name=" + name + ", age=" + age + "]";}}


得到类的字节码文件测试demo;

package fanshe;/** * @author Angus *反射;通过Class文件对象,去使用构造方法,成员变量,成员方法 * *怎么得到Class文件对象? *A:Object对象的getClass方法 *B:数据类型静态的class属性 *C;类 Class的forName(String className)  返回与带有给定字符串名的类或接口相关联的 Class 对象。 */public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {//方式一person p = new person();Class c = p.getClass();person p2 = new person();Class c2 = p.getClass();System.out.println(p == p2); //falseSystem.out.println(c == c2); //true   字节码文件只能是一个//方式二Class c3 = person.class;System.out.println(c==c3); //true//方式三Class c4 = Class.forName("fanshe.person");//路径System.out.println(c==c4); //true}}

反射获取构造方法并使用

package fanshe;import java.lang.reflect.Constructor;/** * @author Angus *反射获取构造方法并使用 * *构造方法:Constructor  *成员变量:Field *成员方法:Method */public class ReflectDemo2 {public static void main(String[] args) throws ClassNotFoundException {Class c = Class.forName("fanshe.person");//public Constructor<?>[] getConstructors()//返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法sssConstructor[] constructors = c.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}System.out.println("------------------------------");//getDeclaredClasses这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口Constructor[] declaredConstructors = c.getDeclaredConstructors();for (Constructor constructor : declaredConstructors) {System.out.println(constructor);}}}

可变参数的使用:

package fanshe;/** *  * @author Angus * *可变参数 *格式: *修饰符  返回值类型 方法名(数据类型... 变量) *{ * *} *注意:变量其实为一个数据 *如果你的方法需要可变参数的数据最好定义在末尾 * */public class ArgsDemo {public static void main(String[] args) {int a = 10;int b = 20;int c = 30;System.out.println(sum1(a,b));System.out.println(sum2(a,b,c));//......多个数求和呢?int d = 40;System.out.println(sun3(a,b,c,d));System.out.println(sun4(a,b,c,d));}/* * 两个数就和 */private static int sum1(int a, int b) {return a+b;}private static int sum2(int a, int b, int c) {// TODO Auto-generated method stubreturn a+b+c;}/** * 可变参数的使用 * @param x * @return */private static int sun3(int... x){int result = 0;for(int i :x){result += i;}return result;}/** * 第一个参数传递给y  剩下的封装数据给x   * 如果int y写到x后边会报错,应为数据全部封装成数据给力x。。。 * @param y * @param x * @return */private static int sun4(int y ,int... x){int result = 0;for(int i :x){result += i;}return result;}}

getConstructor方法使用;

package fanshe;import java.lang.reflect.Constructor;/** * @author Angus *反射获取构造方法并使用 * *构造方法:Constructor  *成员变量:Field *成员方法:Method */public class ReflectDemo2 {public static void main(String[] args) throws Exception {Class c = Class.forName("fanshe.person");//public Constructor<?>[] getConstructors()//返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法sssConstructor[] constructors = c.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}System.out.println("------------------------------");//getDeclaredClasses这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口Constructor[] declaredConstructors = c.getDeclaredConstructors();for (Constructor constructor : declaredConstructors) {System.out.println(constructor);}System.out.println("------------------------------");//public Constructor<T> getConstructor(Class<?>... parameterTypes)Constructor con = c.getConstructor();//通过构造对象创建对象//public T newInstance(Object... initargs)Object newInstance = con.newInstance();System.out.println(newInstance); //person [name=null, age=0]}}


效果;



获取带参构造并使用

package fanshe;import java.lang.reflect.Constructor;/** * @author Angus *获取带参构造并使用 * */public class ReflectDemo2 {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c = Class.forName("fanshe.person");//获取构造器对象//Class[] calsses = new Class[2];//calsses[0] = String.class;//calsses[1] = int.class;//Constructor con = c.getConstructor(calsses);//改进//Constructor com = c.getConstructor(new Class[]{String.class,int.class});//最终Constructor con = c.getConstructor(String.class,int.class);//创建对象Object newInstance = con.newInstance("Angus",26);System.out.println(newInstance);//输出结果:person [name=Angus, age=26]}}

获取公共成员变量并使用

package fanshe;import java.lang.reflect.Constructor;import java.lang.reflect.Field;/** * @author Angus *获取公共成员变量并使用 *getFields 获取公共的成员变量 */public class ReflectDemo2 {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c = Class.forName("fanshe.person");//获取公共成员变量对象//Field[] fields = c.getFields();  ////for (Field field : fields) {//System.out.println(field);////public java.lang.String fanshe.person.name//}//System.out.println("---------------------------------");////获取所有的成员比那里//Field[] declaredFields = c.getDeclaredFields();//for (Field field : declaredFields) {//System.out.println(field);//}System.out.println("---------------------------------");Constructor con = c.getConstructor();Object obj = con.newInstance();//获取一个成员变量//public void set(Object obj,Object value)Field field = c.getField("name");  //只能公共的对象field.set(obj, "Angus");System.out.println(obj);//person [name=Angus, age=0]}}

获取私有成员变量并使用

package fanshe;import java.lang.reflect.Constructor;import java.lang.reflect.Field;/** * @author Angus *获取私有成员变量并使用 *getFields 获取公共的成员变量 * *public static void setAccessible(AccessibleObject[] array,boolean flag) *使用单一安全性检查(为了提高效率)为一组对象设置 accessible 标志的便捷方法。  */public class ReflectDemo2 {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c = Class.forName("fanshe.person");//创建对象Constructor con = c.getConstructor();Object obj = con.newInstance();//赋值Field field = c.getField("name"); //私有的会报错field.set(obj, "Angus");Field declaredField = c.getDeclaredField("age");declaredField.setAccessible(true);//设置私有可访问declaredField.set(obj, 26);System.out.println(obj);//person [name=Angus, age=26]}}

获取成员方法并使用

package fanshe;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * @author Angus * 获取成员方法并使用 * public Object invoke(Object obj, Object... args) * 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 */public class ReflectDemo2 {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c = Class.forName("fanshe.person");//创建对象Constructor con = c.getConstructor();Object obj = con.newInstance();//获取方法//所有公共方法,包括父亲的Method[] methods = c.getMethods(); for (Method method : methods) {//System.out.println(method);}//获取本类的所有方法Method[] declaredMethods = c.getDeclaredMethods();for (Method method : declaredMethods) {//System.out.println(method);}//无参无返回值Method method1 = c.getMethod("show", null);method1.invoke(obj, null);System.out.println("--------------------------");//带参数无返回值Method method2 = c.getMethod("function", String.class);method2.invoke(obj, "Angus");System.out.println("--------------------------");//带多个参数有返回值Method method3 = c.getMethod("returnValue", String.class,int.class);Object invoke = method3.invoke(obj, "Angus",26);System.out.println(invoke);System.out.println("--------------------------");//私有方法的调用Method m4 = c.getDeclaredMethod("hello", null);m4.setAccessible(true);m4.invoke(obj, null);}}

结果:



反射运行配置文件中的内容

package fanshe;import java.io.FileNotFoundException;import java.io.FileReader;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.Properties;/** * @author Angus *反射运行配置文件中的内容 */public class Test {public static void main(String[] args) throws Exception {Properties prop = new Properties();FileReader fr = new FileReader("test.properties");prop.load(fr);fr.close();//获取类名String className = prop.getProperty("className");//获取方法名String methodName = prop.getProperty("methodName");//获取字节码对象Class c = Class.forName(className);Constructor con = c.getConstructor();Object obj = con.newInstance();Method m = c.getMethod(methodName, null);m.invoke(obj, null);}}

配置文件:


Student类


这样若果获取别的类的方法属性信息,可以直接修改属性文件了。。。。


反射滤过泛型检测。。。

有一个ArrayList<Integer>对象,在集合中添加一个字符串数据,如何实现。。。。

package fanshe;import java.lang.reflect.Method;import java.util.ArrayList;/** * @author Angus *有一个ArrayList<Integer>对象,在集合中添加一个字符串数据,如何实现。。。。 */public class ArrayListTest {public static void main(String[] args) throws Exception{ArrayList<Integer> array = new ArrayList<>();//获取字节码问价你对象Class c = array.getClass();Method m = c.getMethod("add", Object.class);m.invoke(array, "hello");m.invoke(array, "world");m.invoke(array, "java");System.out.println(array);}}

结果:



最后附上JDK使用文档API 下载





1 0
原创粉丝点击