黑马程序员——反射

来源:互联网 发布:特效照片制作软件 编辑:程序博客网 时间:2024/04/30 23:09


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

反射:

     是指程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象方法的功能称为java语言的反射机制。

 

     如果要使用反射,就要先获取到类的字节码文件对象(.class),那么获取字节码文件对象有三种方式:

       1、只要是数据类型,都可以通过类型名称,直接.class获取。

       2、创建类对象,调用Object类中的getClass()方法。

       3、知道类的路径名称,调用Class类中的forName(String className)方法。此方法会报出“ClassNotFoundException”编译期异常。

class Demo {private int age;public Demo() {}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class ReflectDemo {public static void main(String[] args) {// 第一种方式Class c1 = Demo.class;        //第二种方式Demo d = new Demo();Class c2 = d.getClass();//第三种方式try{Class c3 = Class.forName("Test2.ReflectDemo");}catch(ClassNotFoundException ce){ce.printStackTrace();}}}

 注意:在开发中通常使用第三种方式,所以要掌握。

      

     在获取了字节码文件对象后,我们就要通过此对象去查看类的信息,可以获取类的构造方法(Constructor)、成员变量(Field)、成员方法(Method)

     

     ConstructorFieldMethod都是继承自AccessibleObject类。该类提供将反射的对象标记为在使用时取消默认Java语言访问控制检查的能力。

     对此AccessibleOngect类提供了方法:public void setAccessible(boolean flag);

     如果值为true则指示反射的对象在使用是应该取消Java语言访问检查。为false则指示反射的对象应该实施Java语言访问检查。所以该方法也被称为暴力访问。    

 

一、获取构造方法:

Constructor类提供了关于类的单个构造方法的信息以及对它的访问权限。

 

1、获取指定的构造方法:

        A、只能获取指定公共构造方法

      public Constructor getConstructor(Class... argeName);

    B、获取任意指定构造方法(包括私有构造)

           Public Constructor getDeclaredConstructor(Class... argeName);

2、获取所有的构造方法:

    A、只能获取所有公共构造方法

       public Constructor[] getConstructors();

    B、获取所有任意构造方法(包括私有构造)

       Public Constructor[] getDeclaredConstructors();

 

 在获取了构造方法后,我们可以通过Constructor类的newInstance(Object...args)方法,创建此类的一个新实例:

import java.lang.reflect.Constructor;class Person {
        //私有成员变量private String name;public Person() {System.out.println("public Person");}//私有带参构造private Person(String name){System.out.println("private Person");this.name = name;}@Overridepublic String toString() {return "Person [name=" + name + "]";}}public class ReflectDemo {public static void main(String[] args) throws Exception {        Class c = Class.forName("Test2.Person");                //避免访问不到私有构造,尽量使用带Declared的方法和暴力访问方法        Constructor con = c.getDeclaredConstructor(String.class);        con.setAccessible(true);        /**         * 注意:访问的是什么数据类型的参数构造,         *          因此创建的实例也要是对应的数据类型。         *          无参则不需要         */        Object obj = con.newInstance("王一");        System.out.println(obj);}
        /**
         *结果:
         *    private Person         *    Person [name=王一]
         */}

 

二、获取成员变量:

   Field类提供有关类或接口的单个字段的信息,以及对它的动态访问权限。

   1、获取指定的成员变量:

      A、只能获取指定公共成员变量

      public Field getField(String name);

  B、获取任意指定成员变量(包括私有变量)

           Public Field getDeclaredField(String name);

   2、获取所有的成员变量:

    A、只能获取所有公共成员变量

       public Field[] getFields();

    B、获取所有任意成员变量(包括私有变量)

       Public Field[] getDeclaredFields();

 

  在获取成员变量后,我们可以通过构造方法创建的新实例,以及Field类的get()和set()来获取和设置成员变量:

import java.lang.reflect.Constructor;import java.lang.reflect.Field;class Person {// 私有成员变量private String name;public Person() {System.out.println("public Person");}// 私有带参构造private Person(String name) {System.out.println("private Person");this.name = name;}@Overridepublic String toString() {return "Person [name=" + name + "]";}}public class ReflectDemo {public static void main(String[] args) throws Exception {Class c = Class.forName("Test2.Person");// 避免访问不到私有构造,尽量使用带Declared的方法和暴力访问方法Constructor con = c.getDeclaredConstructor();con.setAccessible(true);Object obj = con.newInstance(); // 避免访问不到私有成员变量,尽量使用带Declared的方法和暴力访问方法Field f = c.getDeclaredField("name");f.setAccessible(true);        //获取变量,还没赋值,打印出默认值nullf.get(obj);System.out.println(obj);//设置变量f.set(obj, "王一");System.out.println(obj);}/** * 结果: *       public Person *       Person [name=null] *       Person [name=王一] */}

   

三、获取成员方法:

   Method类提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。

   1、获取指定的成员方法:

      A、只能获取指定公共成员方法

      public Field getMethod(String name,Class...argsName);

  B、获取任意指定成员方法(包括私有方法)

           Public Field getDeclaredMethod(String name,Class...argsName);

   2、获取所有的成员方法:

  A、只能获取所有公共成员方法

       public Method[] getMethod();

  B、获取所有任意成员方法(包括私有方法)

       Public Method[] getDeclaredMethods();

在获取成员方法后,我们可以通过构造方法创建的新实例,以及Method类的getName()和invoke(Object obj,Object...args)来获取和设置成员方法:

import java.lang.reflect.Constructor;import java.lang.reflect.Method;class Person {private String name;public Person() {System.out.println("public Person");}private String method(String str) {return str;}@Overridepublic String toString() {return "Person [name=" + name + "]";}}public class ReflectDemo {public static void main(String[] args) throws Exception {Class c = Class.forName("Test2.Person");// 避免访问不到私有构造,尽量使用带Declared的方法和暴力访问方法Constructor con = c.getDeclaredConstructor();con.setAccessible(true);Object obj = con.newInstance();// 避免访问不到私有成员方法,尽量使用带Declared的方法和暴力访问方法Method m = c.getDeclaredMethod("method", String.class);m.setAccessible(true);// 获取方法名String name = m.getName();System.out.println(name);//设置方法参数String str = (String)m.invoke(obj, "Hello");System.out.println(str);}/** * 结果:  *          public Person *          method *          Hello  */}

 

总结:

1、通过Constructor、Field、Method三个类的方法可以发现,想要获取到私有的类成员,使用的方法必须是有带Declared关键字的。而当我们用反射访问一个类的时候,并不能知道有没有私有成员,所以为了避免无法获取私有成员,应该都要优先使用带Declared的方法。

2、使用带Declared的方法是我们可以获取到私有成员的外部信息,但并不代表就可以去访问内部资源。所以为了避免无法访问私有成员的内容,应该都要使用成员对象调用setAccessible(boolean flag)方法。

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老鼠添过的盘子怎么办 ie浏览器页面显示网页错误怎么办 Ⅵvo手机声音小怎么办 小米手机预约错了怎么办 小米note二手没解锁怎么办 艾灸后脸色越黑怎么办 淘宝软件类目不能上架宝贝怎么办 ae中没有mpg格式怎么办 淘宝小二处理不公怎么办 遇到卖保险的人怎么办 租房合同没理家电清单怎么办 普雪油烟机坏了怎么办 我累了 真的累了怎么办 u盘15g变成4g了怎么办 属兔的买了东户怎么办 玩时时彩输了2万怎么办 胸变的又软又小怎么办 u盘16g变成4g了怎么办 1岁宝宝吃了就吐怎么办 脚崴了肿了很痛怎么办 九格拼图5在9那怎么办 4s锁屏密码忘了怎么办 6p触屏偶尔乱跳怎么办 新办劳务公司的劳务资质怎么办 汽车没电了打不着火怎么办 吃凉的甜的牙疼怎么办 学车对点对不上怎么办 发现老公有外遇最明智的怎么办 想开个童装店但是没经验怎么办 母乳不够吃宝宝又不喝奶粉怎么办 掉头发很厉害怎么办有什么偏方 红米2a刷死机了怎么办 公司退市我们买的股票怎么办 黑魂3把npc杀了怎么办 摔倒了膝盖摔肿了又痛怎么办 厕所堵了怎么办疏通马桶有妙招 月经不来怎么办如何让它快点来 苹果手机进水了开不了机怎么办 苹果5s进水了怎么办修要多少钱 吃了过期3年的药怎么办 离婚后孩子的抚养费不给怎么办