zoukankan      html  css  js  c++  java
  • Java中的反射

    一,什么是反射

    1,反射机制是在 运行状态 中:

    对于任意一个类,都能知道这个类的所有属性和方法

    对于任意一个对象,都能够调用它的任意一个方法和属性。

    2,反射提供的功能:

    在运行时判断任意一个对象所属的类

    在运行时构造任意一个类的对象

    在运行时判断任意一个类所具有的成员变量和方法

    在运行时调用任意一个对象的方法

    生成动态代理(动态代理底层用到了反射)

    二,反射入口

    1,获取反射对象(反射入口):就是拿到Class。有三种方法:

    1.1,Class.forName("全类名");需要 包名+类名。需要处理异常

      Class<?> perClazz = Class.forName("sys.person");//推荐这种方式

      System.out.println(perClazz);

    1.2,类名.class

      Class<?> perClazz = Person.class;

      System.out.println(perClazz);

    1.3,对象.getClass();

      Person per = new Person();

      Class<?> perClazz = per.getClass(); //getClass()方法是object提供的

      System.out.println(perClazz);

    2,获取公共的方法

      Class<?> perClazz = Class.forName("sys.person");

      Method[] methods = perClazz.getMethods();

      for(Method method : methods){

        System.out.print(method);

      }

    打印结果:

    public static void sys.Person.staticMethod()

    pulic java.lang.String sys.Person.getName()

    public final native void java.lang.Object.hashCode()

    可以获取本类和父类(Object)中的public方法。

    3,获取接口(多实现)

      Class<?> perClazz = Class.forName("sys.person");

      Class<?>[]  interfaces = perClazz.getInterface();

      for(Class<?> inter : interfaces){

        System.out.println(inter)

      }

    打印结果(Person实现两个MyInterface,MyInterface2):

    interface sys.MyInterface

    interface sys.MyInterface2

    4,获取所有父类(单继承)

      Class<?> perClazz = Class.forName("sys.person");  

      Class<?>  superClass= perClazz.getInterface();

      System.out.println(superClass);

    打印结果:

    class java.lang.Object

    5,获取所有的构造方法

      Class<?> perClazz = Class.forName("sys.person");  

      Constructor<?>[] constructors = perClazz.getConstructors();

      for(Constructor constructor : constructors){

        System.out.println(constructor);

      }

    打印结果:

    public sys.Person(int,java.lang.String);//两个参数

    public sys.Person(int);//一个参数

    public sys.Person();//无参

    6,获取所有的公共属性

      Class<?> perClazz = Class.forName("sys.person");

      Field[] fields = perClazz.getFields();

      for(Field field : fields){

        System.out.println(field);

      }

    打印结果:

    什么也没有,因为Person里定义的变量都是private的。

    如果定义了public变量(public String title),反射才能获取到(public java.lang.String sys.Person.title)。

    7,获取当前类的所有方法(要求:只能是当前类,并忽略访问修饰符限制)

      Class<?> perClazz = Class.forName("sys.person");

      Method[] declaredMethods = perClazz.getDeclaredMethods();

      for(Method method : declaredMethods){

        System.out.print(method);

      }

    打印结果:

    public java.lang.String sys.Person.getName()

    private void sys.Person.privateMethod()

    public static void sys.Person.staticMethod()

    8,获取所有的属性(当前类,忽略访问修饰符)

      Class<?> perClazz = Class.forName("sys.person");

      Field[] fields = perClazz.getDeclaredFields();

      for(Field field : fields){

        System.out.println(field);

      }

    打印结果:

    private int sys.Person.id

    private java.lang.String sys.Person.name

    public java.lang.String sys.Person.title

     9,获取当前反射所代表类(接口)的对象

      Class<?> perClazz = Class.forName("sys.person");

      Object instance = perClazz.newInstance();

      Person per = (Person)instance;//强转

      per.interfaceMehthod();//调用方法

    如果调用成功,说明instance就是Person对象

    三,通过反射获取对象的实例,并操作对象

      Class<?> perClazz = Class.forName("sys.person");

      Person per = (Person)perClazz.newInstance();

      per.setId(1);

      per.setAge(22);

      System.out.println(per.getId() + " : "+ per.getAge());

    可以打印出 id 和 age

    四,通过反射获取对象的实例,操作属性

      Class<?> perClazz = Class.forName("sys.person");

      Person per = (Person)perClazz.newInstance();

      Field idField = perClazz.getDeclaredField(" id ");

      //现在要访问的是private修饰的id,但是private是私有的(私有的只能通过 public void setId()来访问),

      //但是我们通过反射还是想访问private int id 。所以,我们在操作属性之前,需要修改属性访问权限。

      //使用反射时,如果因为访问修饰符限制造成异常,可以通过setAccessible(true)来解决,同理操作私有方法也可以这样做

      idField.setAccessible(true);

      idField.set(per,1); // 相当于 ----->per.setId(1);

      System.out.println( per.getId() );

    五,通过反射获取对象的实例,操作方法

      Class<?> perClazz = Class.forName("sys.person");

      Person per = (Person)perClazz.newInstance();

    1,无参方法

      Method method = perClazz.getDeclaredMethod(" privateMethod ",null);//方法名:privateMethod,参数:null

      //操作方法私有方法时,把访问修饰符屏蔽掉

      method.setAccessible(true);

      method.invoke(per,null);//方法的调用:invoke

    2,有参方法

      Method method2 = perClazz.getDeclaredMethod(" privateMethod2 ",String.class);//方法名:privateMethod2,参数:String类型

      method2.setAccessible(true);

      method2.invoke(per," 张三 ");//调用方法,并传参数

    六,通过反射获取对象的实例,操作构造方法

    1,获取本类全部构造方法(公有的,私有的构造方法都能拿到)

      Class<?> perClazz = Class.forName("sys.person");  

      Constructor<?>[] constructors = perClazz.getDeclaredConstructors();

      for(Constructor constructor : constructors){

        System.out.println(constructor);

      }

    2,获取指定的构造方法(比如:public Person(int id){ this.id = id })

      Class<?> perClazz = Class.forName("sys.person");  

      Constructor<?> constructor = perClazz.getConstructor(int.class);

      System.out.println(constructor);

    打印结果:

    public sys.Person(int);

    3,获取私有的构造方法

    ----->通过getDeclaredConstructor();获取。注意使用setAccessible(true)

    七,

      

      

      

      

      

  • 相关阅读:
    some tips
    ORA00847: MEMORY_TARGET/MEMORY_MAX_TARGET and LOCK_SGA cannot be set together
    Chapter 01Overview of Oracle 9i Database Perfomrmance Tuning
    Chapter 02Diagnostic and Tuning Tools
    变量与常用符号
    Chapter 18Tuning the Operating System
    标准输入输出
    Trace files
    DBADeveloped Tools
    Chapter 03Database Configuration and IO Issues
  • 原文地址:https://www.cnblogs.com/inspred/p/10817134.html
Copyright © 2011-2022 走看看