反射

使用反射的目的一般是为了解除耦合!简称:解耦

用于反射的类

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*/

	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linsa_pursuer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值