【java总结】反射

JAVA反射机制

JAVA有着一个非常突出的动态相关机制:Reflection,即反射机制,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。


public class Person{
    
    public Person() {
         
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    public void reflect1() {
        System.out.println("Java 反射机制 - 调用某个类的方法.");
    }
    public void reflect2(int age, String name) {
        System.out.print("Java 反射机制 - 调用某个类的方法.");
        System.out.println("age -> " + age + ". name -> " + name);
    }
    private String name;
    private int age;
}


public class ReflectTest {
	public static void main(String[] args) throws Exception{
		//通过Object的getClass方法获取Class对象
		Date date1 = new Date(); 
		Date date2 = new Date();
		Class<?> class1=date1.getClass();
		Class<?> class2=date2.getClass();
		System.out.println("类全称: "+class2.getName());//类全称: java.util.Date
		System.out.println("类名: "+class2.getSimpleName());//类名: Date
		System.out.println(class1==class2);//true
		//使用.class的方法,并不需要有该类的对象存在
		Class<?> stringClass=String.class;
		System.out.println("类全称: "+stringClass.getName());//类全称: java.lang.String
		System.out.println("类名: "+stringClass.getSimpleName());//类名: String
		//使用Class.forName()方法
		Class<?> numClass=Class.forName("Collection.Num");
		System.out.println("类全称:"+numClass.getName());//类全称:Collection.Num
		System.out.println("类名:"+numClass.getSimpleName());//类名:Num
		//通过Class的newInstance实例化对象(需要有无参构造方法)
		Date newDate=(Date)class1.newInstance();
		System.out.println(newDate);//Sat Feb 11 21:19:06 GMT+08:00 2017
		//通过Class的newInstance调用对应的构造函数实例化对象
		Person per1=null;
        Person per2=null;
        Person per3=null;
        Person per4=null;
        Class<?> per=Class.forName("Reflect.Person");
        //获得全部构造函数
        Constructor<?>[] constructor=per.getConstructors();
        System.out.println("构造方法: "+constructor[0]);//构造方法: public Reflect.Person(java.lang.String,int)
        System.out.println("构造方法: "+constructor[1]);//构造方法: public Reflect.Person(int)
        System.out.println("构造方法: "+constructor[2]);//构造方法: public Reflect.Person(java.lang.String)
        System.out.println("构造方法: "+constructor[3]);构造方法: public Reflect.Person()
        per1=(Person)constructor[3].newInstance();
        per2=(Person)constructor[2].newInstance("Rollen");
        per3=(Person)constructor[1].newInstance(20);
        per4=(Person)constructor[0].newInstance("Rollen",20);
        System.out.println(per1);[null  0]
        System.out.println(per2);[Rollen  0]
        System.out.println(per3);[null  20]
        System.out.println(per4);[Rollen  20]
        //返回一个类实现的接口
        Class<?> interfaces[]=stringClass.getInterfaces();
        for(int i=0;i<interfaces.length;i++){
        	System.out.println("实现的接口   "+interfaces[i].getName());
        }//实现的接口   java.io.Serializable;实现的接口   java.lang.Comparable;实现的接口   java.lang.CharSequence
        //取得父类
        Class<?> superClass=stringClass.getSuperclass();
        System.out.println("继承的父类为:"+superClass.getName());//继承的父类为:java.lang.Object
        // 取得本类的全部属性
        Field[] field=stringClass.getDeclaredFields();
        for(int i=0;i<field.length;i++){
        	//获取权限修饰符
        	int modify=field[i].getModifiers();
        	String priv = Modifier.toString(modify);
        	//获取属性类型
        	Class<?> type=field[i].getType();
        	System.out.println(priv+"-----"+type.getName()+"-----"+field[i].getName());
        }
        //取得实现的接口或者父类的属性
        System.out.println("---------------------------------");
        Field[] field2=stringClass.getFields();
        for(int i=0;i<field2.length;i++){
        	//获取权限修饰符
        	int modify=field2[i].getModifiers();
        	String priv = Modifier.toString(modify);
        	//获取属性类型
        	Class<?> type=field2[i].getType();
        	System.out.println(priv+"-----"+type.getName()+"-----"+field2[i].getName());
        }
        //通过反射访问修改私有属性
        System.out.println("修改前:"+per4);
        Field privateField=per.getDeclaredField("name");
        privateField.setAccessible(true);
        privateField.set(per4, "Mankind");
        System.out.println("修改后:"+per4);
        //获取某个类的全部方法
        Method[] method=Object.class.getMethods();
        for(int i=0;i<method.length;i++){
        	Class<?> returnType=method[i].getReturnType();
        	Class<?> para[]=method[i].getParameterTypes();
        	int temp=method[i].getModifiers();
        	System.out.println("第"+i+"个方法:");
        	System.out.println("访问权限:"+Modifier.toString(temp));
        	System.out.println("返回类型:"+returnType.getName());
        	System.out.println("方法名:"+method[i].getName());
        	if(para.length!=0){
        		System.out.println("参数列表:");
            	for(int j=0;j<para.length;j++){
            		System.out.println("参数1:"+para[j].getName());
            	}
        	}
        }
        //调用某个类的无参/有参方法
        Method method1=per.getMethod("reflect1");
        method1.invoke(per.newInstance());
        Method method2=per.getMethod("reflect2",int.class,String.class);
        method2.invoke(per.newInstance(),1000,"老王");
        //反射实例:在泛型为Integer的ArrayList中存放一个String类型的对象
        ArrayList<Integer> list = new ArrayList<Integer>();
        Method method3 = list.getClass().getMethod("add", Object.class);
        method3.invoke(list, "Welcome to JAVA");
        System.out.println(list.get(0));
        //通过反射取得并修改数组的信息
        int[] intArray={1,2,3,4,5};
        Class<?> demo=intArray.getClass().getComponentType();
        System.out.println(demo.getName());
        System.out.println(Array.getLength(intArray));
        System.out.println("数组的第一个元素: " + Array.get(intArray, 0));
        Array.set(intArray, 0, 100);
        System.out.println("修改之后数组第一个元素为: " + Array.get(intArray, 0));
        
	}
}


动态代理

对于普通的静态代理,一个代理类需要对应一个事先真实存在的对象,在实际操作中,如果大量使用静态代理必然导致类的膨胀,如果事先并不知道真实角色,该如何使用代理呢?动态代理的存在解决了这样一个问题。可以通过Java的动态代理类来解决。

动态代理的步骤
(1).创建一个实现接口InvocationHandler的类,它必须实现invoke方法
(2).创建被代理的类以及接口
(3).通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
(4).通过代理调用方法

public interface ProxyInterface {
	public void say();
}

public class ProxyObject implements InvocationHandler{
    private Object proxied = null;//这里我们并不知道要代理的对象是谁,所以用一个Object代替
    public ProxyObject(){
        
    }
    public ProxyObject(Object proxied){
        this.proxied  = proxied;
    }
    public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
        System.out.println("你好!");
        return arg1.invoke(proxied, arg2);
    };
}

public class RealObject implements ProxyInterface{
    public void say(){
        System.out.println("i'm talking");
    }
}

public class DynamicProxyTest {
	static void customer(ProxyInterface pi){
        pi.say();
    }
    public static void main(String[] args){
        RealObject real = new RealObject();
        ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));
        customer(proxy);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值