java学习(6) java反射以及应用

1.java反射

1.个人理解:java反射是指能够在程序运行时动态的操作一个类,包括这个类的构造方法,属性,方法。对这个类进行剖析,相当于让程序自己去调用这个类。java反射和RTTI的区别就是:对于反射来说.class文件在编译的时候是不可获取的,所以是在运行时打开和检查.class文件。

2.应用:

1.工厂模式。
在工厂模式下使用反射,可以通过读取一个xml的配置文件进行调用,通过传入classname,调用Class.forname(“classname”)这种方法,可以获得class。这样,调用起来更灵活。如果增加一种业务类型也更方便。程序整体更规则,更美观,利于维护和增量开发。
2.测试场景。

在测试场景下进行进行测试某个类的时候,可以通过反射看到这个类的方法,属性,类型,泛型等各种信息。

3.动态加载。

2.例子

1.获取class类对象(共三种方法)

public class ReflectTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;
        class1 = Class.forName("gwb.TestReflect");/* 用的最多 */
        class2 = new ReflectTest().getClass(); /* 几乎没什么用处 我既然new了一个,为什么还要用反射呢? */
        class3 = ReflectTest.class;
    }

}

2.获取父类和实现的所有接口

public class ReflectTest {
    private static final long serialVersionUID = -123125704934876293L;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Class<?> clazz = Class.forName("");
        /* 获得父类  */
        Class<?> parentClass = clazz.getSuperclass();
        System.out.println("clazz的父类为: " + parentClass.getName());
        /* 获得所有的接口 */
        Class<?> intes[] = clazz.getInterfaces();
        System.out.println("clazz 实现的接口有:");
        for(int i = 0; i < intes.length;i++){
            System.out.println((i+1) + ": " + intes[i].getName());
        }


    }

}

2.获取构造函数

package ReflectTest.src;
import java.lang.reflect.Constructor;

class User{
    private int age;
    private String name;
    public User(){
        super();
    }
    public User(String name){
        super();
        this.name = name;
    }
    public User(int age,String name){
        super();
        this.age = age;
        this.name = name;
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age){
        this.age = age;
    }
    public void setName(String name){
        this.name = name;
    }
    @Override
    public String toString(){
        return "User [age=" + age + ",name = " + name + "]";
    }


}

public class ReflectTest {

    public static void main(String[] args) throws Exception{

        Class<?> class1 = null;
        class1 = Class.forName("ReflectTest.src.User");
        /* 第一种方法:实例化默认构造方法,调用set赋值 */
        User user = (User)class1.newInstance();
        user.setAge(20);
        user.setName("guowenbang");
        System.out.println(user);
        /* 第二种方法:获取全部的构造函数,使用构造函数赋值 */
        /* 获得构造函数的顺序不确定 */
        Constructor<?> cons[] = class1.getConstructors();
        for(int i = 0; i< cons.length;i++){
            Class<?> clazzs[] = cons[i].getParameterTypes();
            System.out.println("cons[" + i + "] (");
            for(int j = 0;j < clazzs.length;j++){
                if(j == clazzs.length - 1)
                    System.out.println(clazzs[j].getName());
                else
                    System.out.println(clazzs[j].getName() + ",");
            }
            System.out.println(")");
        }
        user = (User) cons[2].newInstance("guowen");
        System.out.println(user);
        user = (User) cons[1].newInstance(20,"guowen");
        System.out.println(user);   

    }

}

结果

User [age=20,name = guowenbang]
cons[0] (
)
cons[1] (
int,
java.lang.String
)
cons[2] (
java.lang.String
)
User [age=0,name = guowen]
User [age=20,name = guowen]

3.获取一个类的全部属性

package RefectTest.src;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class TestReflect implements Serializable{
    private static final long serialVersionUID = -1324354324355243242L;
    public static void main(String[]args) throws Exception{
        Class<?> clazz = Class.forName("RefectTest.src.TestReflect");
        Class<?> clazzsuper = clazz.getSuperclass(); /* 由于此类是通过实现接口,所以不能通过getSuperClass的方法来获得Serializable 本身就不是父类嘛。。。 */
        System.out.println("the super class is " + clazzsuper);/* the super class is class java.lang.Object */
        System.out.println("===========本类属性========");
        Field[] fields = clazz.getDeclaredFields(); /* 获取本类的所有属性 包括private public protected */
        for(int i = 0; i < fields.length;i++){
            /* 权限修饰符 */
            int mo = fields[i].getModifiers();
            String priv = Modifier.toString(mo);
            /* 属性类型 */
            Class<?> type = fields[i].getType();
            System.out.println(priv + "  " + type.getName() + "  " + fields[i].getName() + ";");
        }
        System.out.println("==========实现的接口或者父类的属性========");
        Field[] field1 = clazzsuper.getDeclaredFields();
        System.out.println("size " + field1.length);/*  */
        for(int j = 0; j < field1.length;j++){
            int mo = field1[j].getModifiers();
            String priv = Modifier.toString(mo);
            Class<?> type = field1[j].getType();
            System.out.println(priv + " " + type.getName() + " " + field1[j].getName() + ";");
        }
    }
}

4.调用类方法

package gwb2;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestReflect {

    private static final long serialVersionUID = -23498779765678654L;
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        Class<?> clazz = Class.forName("gwb2.TestReflect");
        Method[] method = clazz.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(Modifier.toString(temp) + " ");
            System.out.println(returnType.getTypeName() + "  ");
            System.out.println(method[i].getName() + " ");
            System.out.println("(");
            for(int j = 0;j < para.length;j++){
                System.out.println(para[j].getName() + " " + "arg" + j);
                if(j < para.length-1){
                    System.out.println(",");
                }
            }
            Class<?> exce[] = method[i].getExceptionTypes();
            if(exce.length>0){
                System.out.println(") throws");
                for(int k = 0;k < exce.length;k++){
                    System.out.println(exce[k].getName() + " ");
                    if( k  < exce.length - 1){
                        System.out.println(",");
                    }
                }
            }
            else{
                System.out.println(")");
            }
            System.out.println();
        }

    }

}

5.获取某个类的全部方法

package ReflectTest.src.gwb2;

import java.lang.reflect.Method;

public class TestReflect {

    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        Class<?> clazz = Class.forName("ReflectTest.src.gwb2.TestReflect");
        Method method = clazz.getMethod("reflect1");
        method.invoke(clazz.newInstance());

        method = clazz.getMethod("reflect2", int.class,String.class);
        method.invoke(clazz.newInstance(),20,"张三");

    }
    public void reflect1(){
        System.out.println("java 反射机制 - 调用某一个类的方法1");
    }
    public void reflect2(int age,String name){
        System.out.println("java 反射机制 - 调用某个类的方法2");
        System.out.println("age -> " + age + ".name ->" + name);
    }

}

输出结果:

java 反射机制 - 调用某一个类的方法1
java 反射机制 - 调用某个类的方法2
age -> 20.name ->张三

6.修改类属性

package ReflectTest.src.gwb3;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflect {

    private String proprety = null;
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        Class<?> clazz = Class.forName("ReflectTest.src.gwb3.TestReflect");
        Object obj = clazz.newInstance();
        Field field = clazz.getDeclaredField("proprety");
        field.setAccessible(true);
        field.set(obj, "java 反射机制的demno");
        Method method = clazz.getMethod("getproprety");

        System.out.println("the Proprety:" + field.get(obj));
        System.out.println("the proprety : " + field);
        /* invoke 这里面最开始传入的是clazz.newinstance() 因为这样相当于传入的是一个新的实例,调用的自然也就是新势力的getproprety所以此时是返回null的*/
         String a = (String)method.invoke(obj);
         System.out.println("the proprety  a : " + a);

    }
    public String getproprety(){
        return proprety;
    }

}

7.动态代理

先来一个demo

package gwb3;

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

interface Subject{
    public String say(String name,int age);
}
class RealSubject implements Subject{
    public String say(String name,int age){
        return name +  "  " + age; 
    }
}

class MyInvocationHandler implements InvocationHandler{
    private Object obj = null;
    public Object bind(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
        Object temp = method.invoke(this.obj, args);
        return temp;
    }
}
public class TestReflect {


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyInvocationHandler demo = new MyInvocationHandler();
        Subject sub = (Subject)demo.bind(new RealSubject());
        String info  = sub.say("Rollen",20);
        System.out.println(info);
    }

}

1.那么什么是动态代理呢?

2.那什么是代理呢?

代理是设计模式之一。代理通常充当着中间人的角色。
再来个代理的demo摘自java变成思想。


interface Interface{
    void doSomething();
    void somethingElse(String arg);
}
class RealObject implements Interface{
    public void doSomething(){System.out.println("do Somethis");}
    public void somethingElse(String arg){
        System.out.println("somethingElse " + arg);
    }
}
class SimpleProxy implements Interface{
    private Interface proxied;
    public SimpleProxy(Interface proxied){
        this.proxied = proxied;
    }
    public void doSomething(){
        /* 这个输出就代表额外操作了 */
        System.out.println("SimpleProxy doSomething");
        proxied.doSomething();
    }
    public void somethingElse(String arg){
        /* 这个输出就代表额外操作了 */
        System.out.println("SimpleProxy somethingElse " + arg);
        proxied.somethingElse(arg);
    }
}
public class SimpleProxyDemo {

    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethingElse("bonobo");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /* 传入了两个实现了interface的类 */
        consumer(new RealObject());
        /* 相当于在上面new RealObject的基础上封装了一个类 可以新增一些额外的操作,比如查看代码开销等 */
        consumer(new SimpleProxy(new RealObject()));
    }

}

嗯。从上面来看,这就叫代理。简单归纳一下,当你希望跟踪一个类中的方法的调用。比如查看代码的调用开销,这个时候,你必然不能修改原有的接口啊。不仅容易引入问题而且验证完事之后还不好删除,这时这个代理模式就用上了。其实不只是调用开销,其他的测试也会有用到的。(感觉这个和python中的装饰器原理很像,有什么区别呢,先留一个坑_
ok,现在对于代理基本的意识已经有了,那么什么是动态代理呢?
顾名思义。那就是动态的创建代理,和动态的调用代理。。。。。。。。。。
那现在重写一下上面的普通代理的例子

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Interface{
    void doSomething();
    void somethingElse(String arg);
}
class RealObject implements Interface{
    public void doSomething(){System.out.println("do Somethis");}
    public void somethingElse(String arg){
        System.out.println("somethingElse " + arg);
    }
}
class DynamicProxyHandler implements InvocationHandler{
    private Object proxied;
    public DynamicProxyHandler(Object proxied){
        this.proxied = proxied;
    }
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
        System.out.println("**** proxy: " + proxy.getClass() + " . method: " + method + ",args " + args);
        if(args != null){
            for(Object arg : args){
                System.out.println("  " + arg);
            }

        }
        return method.invoke(proxied, args);
        /*
         *  此处可以有优化,比如进行函数的过滤,因为走的是代理流程的化 这个是函数调用的入口,所以可以这样
         *  if(method.getName().equals("MethodName"))
         *  {
         *    dosomethind...
         *  }*/
    }
}

 class SimpleDynamicProxy{
    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethingElse("bonobo");
    }
    public static void main(String[] args){
        RealObject real = new RealObject();
        consumer(real);
        /* 通过调用newProxyInstance可以创建动态代理 */
        /* 1.需要一个类加载器   2.一个用户希望代理能够实现的接口列表 3.一个实现了InvocationHandler的类 */
        /* 这个动态代理可以将所有调用重定向到调用到处理器,所以在调用处理器中要传入一个 对象的引用,这样这个调用就转换了 */
        Interface proxy = 
                (Interface)Proxy.newProxyInstance
                (Interface.class.getClassLoader(), 
                        new Class[]{Interface.class}, 
                        new DynamicProxyHandler(real));
        //
        consumer(proxy);

    }
}

8.工厂模式

9.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值