Java基础强化——Reflection

1、反射:在程序运行时通过一个类的对象获取这个类的信息的方法。

2、Class类:在java里万事万物皆对象,可以理解为是Class类的对象,Class有一些方法可以由类的对象获取类的信息。获取一个class的Class实例有三种办法,如下:

package reflection;

public class ReflectionDemo {
	
	public static void main(String args[]) {
		// 实例对象如何表示
		ClassDemo classDemo = new ClassDemo();
	
		// ClassDemo是类,其实也是一个实例对象是基于Class的。
		//方法1:(任何一个类都有一个隐含的成员变量class)
		Class c1 = ClassDemo.class; 
		
		//方法2:(通过getClass()方法获取一个对象的类信息)
		Class c2 = classDemo.getClass(); 
		
		// 两种表达式相同的
		System.out.println(c1 == c2);
		
		//方法3:通过Class的forName()方法
		Class c3 = null;
		try {
			c3 = Class.forName("reflection.ClassDemo");
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		// 也是相等的
		System.out.println(c2 == c3);
		
		// 可以通过c1,c2, c3创建该类的对象
		try {
			ClassDemo classDemo2 = (ClassDemo)c1.newInstance(); // 根据实际情况进行强制类型转换
			classDemo2.print();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
}

// classdemo 类
class ClassDemo{
	
	void print() {
		System.out.println("class demo");
	}	
}

3、静态加载和动态加载:静态加载时值程序在编译期的时候就完成了加载编译,比如new对象就是编译时加载的,已经创建好了对象实例。而动态加载时指在运行时需要使用的时候才进行加载,绕过编译且不报错。

4、通过反射API获取类信息:使用Class的提供的方法可以获取一个对象的类的信息,包括成员变量,成员方法,构造方法,甚至包括接口信息,继承关系等。Java的反射API提供的Field类封装了成员变量的所有信息,Method对象封装了方法的所有信息,Constructor对象封装了构造方法的所有信息。

5、动态代理:JDK提供的动态创建接口对象的方式,即没有实现类但是在运行期动态创建了一个接口对象的方式。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义一个InvocationHandler实例,它负责实现接口的方法调用;
// 通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:(使用的`ClassLoader`;需要实现的接口数组;用来处理接口方法调用的`InvocationHandler`实例。)
//将返回的`Object`强制转型为接口。 

public class Main {
	
	public static void main(String args[]) {
		
		InvocationHandler handler = new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }	
		};
		
		Hello hello = (Hello) Proxy.newProxyInstance(
	            Hello.class.getClassLoader(), // 传入ClassLoader
	            new Class[] { Hello.class },  // 传入要实现的接口
	            handler); // 传入处理调用方法的InvocationHandler
	        hello.morning("Bob");
	}
}

interface Hello {
    void morning(String name);
}

6、代理模式和反射机制:动态代理是设计模式当中代理模式的一种(为其他对象提供一种代理以控制这个对象的访问),JDK的动态代理主要是使用的是反射机制。常应用于AOP(面向切面编程)、RPC(远程过程调用),反编译,EventBus 2.x,动态生成类框架等。

优点:运行期类型的判断,动态类加载,动态代理使用反射;

缺点:性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值