zoukankan      html  css  js  c++  java
  • 浅谈反射

     

    1:反射(理解)
    (1)类的加载及类加载器
    (2)反射:
           通过字节码文件对象,去使用成员变量,构造方法,成员方法
    (3)反射的使用
           A:通过反射获取构造方法并使用

               

    package com.itheima.test;

    public class Person {
    private String name;
    int age;
    public String address;

    public Person() {
    }

    private Person(String name) {
    this.name = name;
    }

    Person(String name, int age) {
    this.name = name;
    this.age = age;
    }

    public Person(String name, int age, String address) {
    this.name = name;
    this.age = age;
    this.address = address;
    }

    public void show() {
    System.out.println("show");
    }

    public void method(String s) {
    System.out.println("method " + s);
    }

    public String getString(String s, int i) {
    return s + "---" + i;
    }

    private void function() {
    System.out.println("function");
    }

    @Override
    public String toString() {
    return "Person [name=" + name + ", age=" + age + ", address=" + address
    + "]";
    }

    }

     

     

    主类:

    //获取公共构造方法
    Class c=Class.forName("com.itheima.test.Person");
    Constructor[] constructors = c.getConstructors();
    for (Constructor constructor : constructors) {
    System.out.println(constructor);
    }

    输出结果:

    public com.itheima.test.Person(java.lang.String,int,java.lang.String)
    public com.itheima.test.Person()

    主类:

    //获取所有构造方法
    Class c=Class.forName("com.itheima.test.Person");
    Constructor[] declaredConstructors = c.getDeclaredConstructors();
    for (Constructor constructor : declaredConstructors) {
    System.out.println(constructor);
    }

    输出结果:

    private com.itheima.test.Person(java.lang.String)
    com.itheima.test.Person(java.lang.String,int)
    public com.itheima.test.Person(java.lang.String,int,java.lang.String)
    public com.itheima.test.Person()

    主类:

    Class c=Class.forName("com.itheima.test.Person");
    //获取无参构造函数
    Constructor con=c.getConstructor();
    System.out.println(con);
    //获取有参构造函数对象
    Constructor con1=c.getConstructor(String.class, int.class, String.class);
    Object instance = con1.newInstance("fan",15,"1234");
    System.out.println(con1);
    System.out.println(instance);
    //获取有参构造函数对象
    Constructor con2=c.getConstructor(String.class,int.class);
    Object instance2 = con2.newInstance("fab1",15);
    System.out.println(con2);
    System.out.println(instance2);

    输出结果:

    public com.itheima.test.Person()
    public com.itheima.test.Person(java.lang.String,int,java.lang.String)
    Person [name=fan, age=15, address=1234]
    public com.itheima.test.Person(java.lang.String,int)
    Person [name=fab1, age=15, address=null]

    主类:

    Class c = Class.forName("com.itheima.test.Person");
    // 获取私有构造方法对象
    // NoSuchMethodException:每个这个方法异常
    // 原因是一开始我们使用的方法只能获取公共的,下面这种方式就可以了。
    Constructor con = c.getDeclaredConstructor(String.class);
    System.out.println(con);
    // 用该私有构造方法创建对象
    // IllegalAccessException:非法的访问异常。
    // 暴力访问
    con.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。
    Object obj = con.newInstance("风清扬");

    System.out.println(obj);

    输出结果 :

    private com.itheima.test.Person(java.lang.String)
    Person [name=风清扬, age=0, address=null]

                B:通过反射获取成员变量并使用

    Class c = Class.forName("com.itheima.test.Person");
    //获取所有的公共成员变量
    Field[] fields = c.getFields();
    for (Field field : fields) {
    System.out.println(field);
    }
    System.out.println("---------------");
    //获取所有的成员变量
    Field[] fields2 = c.getDeclaredFields();
    for (Field field : fields2) {
    System.out.println(field);
    }
    System.out.println("---------------");
    //获取单个的成员变量
    // 通过无参构造方法创建对象
    Constructor con = c.getConstructor();
    Object obj = con.newInstance();
    System.out.println(obj);
    Field field = c.getField("address");
    field.set(obj,"fas");
    System.out.println(obj);

      输出结果:

    public java.lang.String com.itheima.test.Person.address
    ---------------
    private java.lang.String com.itheima.test.Person.name
    int com.itheima.test.Person.age
    public java.lang.String com.itheima.test.Person.address
    ---------------
    Person [name=null, age=0, address=null]
    Person [name=null, age=0, address=fas]


           C:通过反射获取成员方法并使用

      主类:

    Class c = Class.forName("com.itheima.test.Person");
    //获取自己和父亲方法的公共方法
    Method[] methods = c.getMethods();
    for (Method method : methods) {
    System.out.println(method);
    }
    System.out.println("----------");
    //获取自己的所有的方法
    Method[] methods2 = c.getDeclaredMethods();
    for (Method method : methods2) {
    System.out.println(method);
    }
    System.out.println("----------");
    //获取单个的方法
    Constructor con = c.getConstructor();
    Object obj = con.newInstance();
    Method m2 = c.getMethod("method", String.class);
    m2.invoke(obj, "hello");
    System.out.println("----------");

    输出结果:

    public java.lang.String com.itheima.test.Person.toString()
    public java.lang.String com.itheima.test.Person.getString(java.lang.String,int)
    public void com.itheima.test.Person.method(java.lang.String)
    public void com.itheima.test.Person.show()
    public final void java.lang.Object.wait() throws java.lang.InterruptedException
    public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    public native int java.lang.Object.hashCode()
    public final native java.lang.Class java.lang.Object.getClass()
    public boolean java.lang.Object.equals(java.lang.Object)
    public final native void java.lang.Object.notify()
    public final native void java.lang.Object.notifyAll()
    ----------
    public java.lang.String com.itheima.test.Person.toString()
    public java.lang.String com.itheima.test.Person.getString(java.lang.String,int)
    public void com.itheima.test.Person.method(java.lang.String)
    public void com.itheima.test.Person.show()
    private void com.itheima.test.Person.function()
    ----------
    method hello
    ----------


    (4)反射案例
           A:通过反射运行配置文件的内容

    Class c4 = Class.forName("cn.itcast_01.Person");
    System.out.println(c == c4);

           B:通过反射越过泛型检查

    ArrayList<String> arrayList=new ArrayList<String>();//指定泛型为Integer
    Class c=arrayList.getClass();//获取Class文件对象
    Method addMethod=c.getDeclaredMethod("add",Object.class);//获取Class文件对象中的add()方法
    Student s=new Student("fan",20);
    addMethod.invoke(arrayList, "asdfg");//越过泛型检查,添加String类型
    addMethod.invoke(arrayList, s);//越过泛型检查,添加Student类型
    System.out.println(arrayList);//结果为:[asdfg, Student [name=fan, age=20]]


           C:通过反射给任意的一个对象的任意的属性赋值为指定的值
    (5)动态代理

             StudentDao类

    public interface StudentDao {
              public abstract void login();

        public abstract void regist();
    }

      StudentImpl类

    public class StudentDaoImpl implements StudentDao {

    @Override
    public void login() {
    System.out.println("登录功能");
    }

    @Override
    public void regist() {
    System.out.println("注册功能");
    }

    }

    //代理对象类 MyInvocationHandler

    public class MyInvocationHandler implements InvocationHandler {
    private Object target; // 目标对象

    public MyInvocationHandler(Object target) {
    this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    System.out.println("权限校验");
    Object result = method.invoke(target, args);
    System.out.println("日志记录");
    return result; // 返回的是代理对象
    }
    }

     主类:

    StudentDao sd = new StudentDaoImpl();
    MyInvocationHandler handler2 = new MyInvocationHandler(sd);
    StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler2);
    proxy2.login();
    proxy2.regist();

  • 相关阅读:
    安装IIS的郁闷之旅
    设置WPF窗口相对于非WPF窗口的位置
    钓鱼记
    java拾遗
    人间四月芳菲尽
    [linux] x server can not start under VMWare
    如果没有开源软件没有免费软件,这个世界会怎么样?评[盖茨北大演讲遭遇开源人士抗议]
    程序员的面包
    2007中国软件英雄会-七年的等待
    sysbench安装
  • 原文地址:https://www.cnblogs.com/fjkgrbk/p/Reflect.html
Copyright © 2011-2022 走看看