使用反射的目的一般是为了解除耦合!简称:解耦
一.检查obj的实际类型以及全部信息
二.访问对象具体的属性
三.改变属性值
四.读取resources里的conf下的demo.xml文件
五.反射读取注解
注解的两个类:
动态加载类:
用于反射的类
package cn.tedu.tstore.reflect;
public class Foo {
int age;
double price;
public int test(int a) {
return a+1;
}
@Override
public 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.Foo
class cn.tedu.tstore.reflect.Foo
Foo [age=0, price=0.0]
属性名:
age
0*/
}
}
三.改变属性值
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
属性值:
8
Foo [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 动态加载类
//获得当前的ClassLoader
ClassLoader classLoader = Demo4.class.getClassLoader();
//ClassLoader 提供了两个常用的功能
//1.用于动态加载类——返回Class
//2.从package 中加载资源: 图片,xml等——返回InputStream
String 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 {
@Test
public void demo() {
System.out.println("Hello World");
}
@Test
public void test() {
System.out.println("Hello Kitty");
}
@Test
public 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.TestCase
public void cn.tedu.tstore.reflect.TestCase.demo()
demo
void
public void cn.tedu.tstore.reflect.TestCase.demo()
Hello World
public void cn.tedu.tstore.reflect.TestCase.add()
add
void
public void cn.tedu.tstore.reflect.TestCase.add()
Add
public void cn.tedu.tstore.reflect.TestCase.test()
test
void
public void cn.tedu.tstore.reflect.TestCase.test()
Hello Kitty*/
}
}