反射

来源:互联网 发布:linux mysql 编辑:程序博客网 时间:2024/06/01 10:27
使用反射的目的一般是为了解除耦合!简称:解耦

用于反射的类

package cn.tedu.tstore.reflect;public class Foo {int age;double price;public int test(int a) {return a+1;}@Overridepublic String toString() {return "Foo [age=" + age + ", price=" + price + "]";}}

一.检查obj的实际类型以及全部信息

package cn.tedu.tstore.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class Demo1 {public static void main(String[] args) {test(5);test("5");test('5');List<String> list = new ArrayList<String>();list.add("Tom");Iterator<String> ite = list.iterator();//检查ite的类型System.out.println(ite.getClass());}public static void test(Object obj) {//obj 实际的类型是什么//利用反射,动态检查obj的实际类型Class cls = obj.getClass();System.out.println(cls);//还可以检查类型全部的信息//Declared 声明的,Field 字段,属性//getDeclaredFields 返回cls中声明的全部属性Field[] fields = cls.getDeclaredFields();for(Field field : fields) {System.out.println(field);}//检查类中声明的方法信息Method[] methods = cls.getDeclaredMethods();for(Method method : methods) {System.out.println(method);}//检查类中声明的构造器信息Constructor[] cons = cls.getConstructors();for(Constructor con : cons) {System.out.println(con);}}}

二.访问对象具体的属性

package cn.tedu.tstore.reflect;import java.lang.reflect.Field;import java.util.Scanner;public class Demo2 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {/** * 动态加载类到内存方法区中 */Scanner in = new Scanner(System.in);System.out.println("输入类名: ");String className = in.nextLine();Class cls = Class.forName(className);System.out.println(cls);//利用反射检查cls 的内部结构//动态创建对象Object obj = cls.newInstance();System.out.println(obj);//动态访问对象的属性System.out.println("属性名: ");String name = in.nextLine();//找到需要访问的属性信息Field field = cls.getDeclaredField(name);//在对象上查找属性对应的值Object val = field.get(obj);System.out.println(val);/*运行结果如下:输入类名: cn.tedu.tstore.reflect.Fooclass cn.tedu.tstore.reflect.FooFoo [age=0, price=0.0]属性名: age0*/}}

三.改变属性值

package cn.tedu.tstore.reflect;import java.lang.reflect.Field;import java.util.Scanner;public class Demo3 {public static void main(String[] args) throws Exception {Scanner in = new Scanner(System.in);System.out.println("类名: ");String className = in.nextLine();System.out.println("属性名: ");String name = in.nextLine();System.out.println("属性值: ");String value = in.nextLine();//动态加载类Class cls = Class.forName(className);//动态创建对象Object obj = cls.newInstance();//检查对象默认属性System.out.println(obj);//查询属性信息,查询当前类中声明的属性信息Field fld = cls.getDeclaredField(name);Object val = null;//根据fld的类型转换输入数据。if(fld.getType()==int.class) {val = Integer.parseInt(value);}else if(fld.getType() == double.class) {val=Double.parseDouble(value);}//设置obj对象的属性值fld.set(obj, val);//展示设置结果System.out.println(obj);/*运行结果如下:类名: cn.tedu.tstore.reflect.Foo属性名: age属性值: 8Foo [age=0, price=0.0]Foo [age=8, price=0.0]*/}}

四.读取resources里的conf下的demo.xml文件

package cn.tedu.tstore.reflect;import java.io.IOException;import java.io.InputStream;public class Demo4 {public static void main(String[] args) throws ClassNotFoundException, IOException {//利用ClassLoader 动态加载类//获得当前的ClassLoaderClassLoader classLoader = Demo4.class.getClassLoader();//ClassLoader 提供了两个常用的功能//1.用于动态加载类——返回Class//2.从package 中加载资源: 图片,xml等——返回InputStreamString className = "cn.tedu.tstore.reflect.Foo";Class cls = classLoader.loadClass(className);System.out.println(cls);//读取package中的文件String path = "conf/demo.xml";InputStream in = classLoader.getResourceAsStream(path);byte[] buf = new byte[in.available()];in.read(buf);in.close();String str = new String(buf,"utf-8");System.out.println(str);}}

五.反射读取注解
注解的两个类:

package cn.tedu.tstore.reflect;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface Test {}package cn.tedu.tstore.reflect;public class TestCase {@Testpublic void demo() {System.out.println("Hello World");}@Testpublic void test() {System.out.println("Hello Kitty");}@Testpublic void add() {System.out.println("Add");}}

动态加载类:

package cn.tedu.tstore.reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Scanner;public class Demo5 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {//JUnit4 原型案例Scanner in = new Scanner(System.in);System.out.println("输入类名: ");String className = in.nextLine();//动态加载类Class cls = Class.forName(className);//动态创建对象Object obj = cls.newInstance();//检查类的全部方法Method[] methods = cls.getDeclaredMethods();for(Method method : methods) {System.out.println(method);System.out.println(method.getName());System.out.println(method.getReturnType());//返回当前方法信息中全部的注解method.getAnnotations();//返回当方法上的一个特定注解,如果返回//null 表示没有找到特定注释Test t = method.getAnnotation(Test.class);if(t!=null) {System.out.println(method);method.invoke(obj);}}/*运行结果如下:输入类名: cn.tedu.tstore.reflect.TestCasepublic void cn.tedu.tstore.reflect.TestCase.demo()demovoidpublic void cn.tedu.tstore.reflect.TestCase.demo()Hello Worldpublic void cn.tedu.tstore.reflect.TestCase.add()addvoidpublic void cn.tedu.tstore.reflect.TestCase.add()Addpublic void cn.tedu.tstore.reflect.TestCase.test()testvoidpublic void cn.tedu.tstore.reflect.TestCase.test()Hello Kitty*/}}


原创粉丝点击