java-反射

反射:是动态语言的的关键

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

了解类加载器

// 了解类加载器
	@Test
	public void test1() throws ClassNotFoundException {
		// 系统类加载器 自己编写的的
		ClassLoader cl = this.getClass().getClassLoader();
		System.out.println(cl);
		//扩展类库
		ClassLoader cl2 = cl.getParent();
		System.out.println(cl2);
		//核心类库无法拿到
		ClassLoader cl3 = cl2.getParent();
		System.out.println(cl3);
	}

在这里插入图片描述

重要:

	// 【重要】通过类加载器加载属性文件
	@Test
	public void test2() throws IOException {
		Properties pros = new Properties();

		// pros.load(new FileInputStream("./hello.properties"));
		/*
		 * ClassLoader cl = this.getClass().getClassLoader(); InputStream in =
		 * cl.getResourceAsStream("com/atguigu/java/hello.properties");
		 * pros.load(in);
		 */

		pros.load(this.getClass().getClassLoader().getResourceAsStream("com/atguigu/java/hello.properties"));

		String userName = pros.getProperty("userName");
		String password = pros.getProperty("password");

		System.out.println(userName);
		System.out.println(password);
	}

1 Class类描述类的类
clazz通过描述的对应类的构造器获取实例

/*
 * 1. Java 程序的运行分为两种状态:
 * 编译时:通过 javac 命令,生成零个或多个 .class 字节码文件。(每个 .class 对应一个类)
 * 运行时:通过 java 命令,将零个或多个 .class 字节码文件加载到内存中。(由 JVM 提供的类加载器)
 * 
 * 2. 类用于描述现实生活中的一类事物,类是抽象的,若需要具体到某一个事物,通过 new 关键字创建对象。
 * 可以操作对象的属性,调用对象的方法。
 * (因为在编译时可以确定创建什么类的对象,操作什么属性,调用什么方法)
 * 在某种情况下,我们需要得知并使用一个在编译时完全未知的类,创建其对象,操作其属性,调用其方法
 * 
 * 一、反射机制(Reflection):被视为动态语言的关键,在运行时创建任意类的对象,获取并操作任意对象的属性和方法。
 * 
 * Class 是开启反射的源头!
 * 
 * 如何获取 Class 的实例?
 * 		//1. 通过运行时类的属性 class
 * 		//2. 通过运行时类对象的 getClass()
 * 		//3. 通过 Class 静态方法 forName(String className)
 * 		//4. 通过类加载器(了解)
 * 		 
 *  二、反射的功能:
 *  ①在运行时判断任意类的对象
 *  ②在运行时判断任意类的结构
 *  ③在运行时获取任意类的属性和方法
 *  ④在运行时调用任意类对象的属性和方法
 *  ⑤生成动态代理
 *   
 */
public class ReflectionTest {
	
	//
	/*public <T> T get(Class<T> clazz){
		//---
		return clazz.newInstance();
	}*/
	
	
	@Test
	public void test2() throws ClassNotFoundException{
		//1. 通过运行时类的属性 class
		Class clazz = Person.class;
		System.out.println(clazz);
		
		//2. 通过运行时类对象的 getClass()
		Person p = new Person();
		Class clazz2 = p.getClass();
		System.out.println(clazz2);
		
		//3. 通过 Class 静态方法 forName(String className)
		String className = "com.atguigu.java.Person";
		Class clazz3 = Class.forName(className);
		System.out.println(clazz3);
		
		//4. 通过类加载器(了解)
		ClassLoader cl = this.getClass().getClassLoader();
		Class clazz4 = cl.loadClass(className);
		System.out.println(clazz4);
	}
	
	//反射之前
	@Test
	public void test1(){
		Person p = new Person();
		p.setName("张三");
	}

public class InstanceTest {
	
	//1.在运行时创建类的对象 : newInstance() 方法,该方法默认调用运行时类的无参构造器
	@Test
	public void test1() throws Exception{
		/*Class clazz = Person.class;
		Person p = (Person) clazz.newInstance();
		System.out.println(p);*/
		
		Class<Person> clazz = Person.class;
		Person p = clazz.newInstance();
		System.out.println(p);
	}
	//1. 在运行时获取运行时类的属性
	@Test
	public void test1(){
		Class clazz = Person.class;
		
		//getFields() : 获取所有 public 修饰的属性,包括父类的
		//Field[] fields = clazz.getFields();
		
		//getDeclaredFields() : 获取本类所有声明的属性,包括私有的,不包括父类的
		Field[] fields = clazz.getDeclaredFields();
		
		for (Field field : fields) {
			System.out.println(field.getName());
		}
	}

}

//2. 在运行时获取运行时类属性的完整结构:修饰符 数据类型 属性名
	@Test
	public void test2(){
		Class clazz = Person.class;
		
		Field[] fields = clazz.getDeclaredFields();
		
		for (Field field : fields) {
			//①修饰符
			int mod = field.getModifiers();
			String strMod = Modifier.toString(mod);
			System.out.print(strMod + "\t");
			
			//②数据类型
			Class type = field.getType();
			System.out.print(type + "\t");
			
			//③属性名
			System.out.println(field.getName());
		}
	}
	//7. 在运行时获取运行时类的包
	@Test
	public void test7(){
		Class clazz = Person.class;
		
		Package pk = clazz.getPackage();
		
		System.out.println(pk);
	}
	
	//6. 在运行时获取运行时类的注解
	@Test
	public void test6(){
		Class clazz = Person.class;
		
		Annotation[] annotations = clazz.getAnnotations();
		
		for (Annotation annotation : annotations) {
//			System.out.println(annotation);
			
			MyAnnotation ma = (MyAnnotation) annotation;
			
			System.out.println(ma.value());
		}
	}
	
	//5. 在运行时获取运行时类的内部类
	@Test
	public void test5(){
		Class clazz = Person.class;
		
//		Class[] clazzes = clazz.getClasses();
		
		Class[] clazzes = clazz.getDeclaredClasses();
		
		for (Class class1 : clazzes) {
			System.out.println(class1);
		}
	}
	
	//4. 在运行时获取运行时类的接口
	@Test
	public void test4(){
		Class clazz = Person.class;
		
		Class[] clazzes = clazz.getInterfaces();
		
		for (Class class1 : clazzes) {
			System.out.println(class1);
		}
	}
	
	//3. 【重要】在运行时获取运行时类带泛型父类的泛型类型
	@Test
	public void test3(){
		Class clazz = Person.class;
		
		//1. 获取带泛型的父类类型
		Type type = clazz.getGenericSuperclass();
		
		//2. 参数化类型 com.atguigu.java.Creature<java.lang.String>
		ParameterizedType pt = (ParameterizedType) type;
		
		//3. 获取参数类型
		Type[] types = pt.getActualTypeArguments();
		
		Class cl = (Class) types[0];
		System.out.println(cl.getName()); 
	}
	
	//2. 在运行时获取运行时类带泛型父类的类型: Creature<String> c = new Creature<>();
	@Test
	public void test2(){
		Class clazz = Person.class;
		Type type = clazz.getGenericSuperclass();
		System.out.println(type);//com.atguigu.java.Creature<java.lang.String>
	}
	
	//1. 在运行时获取运行时类的父类
	@Test
	public void test1(){
		Class clazz = Person.class;
		Class superClazz = clazz.getSuperclass();
		System.out.println(superClazz);
	}

动态代理
1 什么是动态代理。


/*
 * 动态代理需要实现接口:InvocationHandler
 * 
 * public Object invoke(Object proxy, Method method, Object[] args)
 * 
 * proxy : 生成的代理对象
 * method : 代理对象需要执行方法的 Method 的实例
 * args : 执行方法需要的参数
 */
public class DynaProxyHandler implements InvocationHandler{
	
	//目标对象
	private Object target;
	
	//生成动态代理对象
	public Object getProxyInstance(Object target){
		this.target = target;
		
		/*
		 * 第一个参数:通常与目标对象的类加载器一致
		 * 第二个参数:通常与目标对象实现的接口一致(实现哪些接收说明有什么方法)
		 * 第三个参数:实现了 InvocationHandler 接口实现类的实例(目的是执行 invoke() 方法)
		 */
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("---------代理开始---------");//面向切面编程
		
		Object obj = method.invoke(target, args);

		System.out.println("---------代理结束---------");
		return obj;
	}

}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值