Java 反射 2

来源:互联网 发布:mac官网彩妆 编辑:程序博客网 时间:2024/05/24 06:58
 

Java 反射

Class

 

            Java 程序汇总的各个 Java 类属于同一类事物,描述这类事物的 Java 类名就是 Class。Class 表示在内存中存储的字节码。

 

           (1)获取字节码的三种方式:

                                          1 、类名.class。 例如:System.class;

                                          2 、对象.getClass()。例如:new Date().getClass();

                                          3、Class.forName("类名")。例如:Class.forName("java.util.Date");


           (2)九个预定义 Class 实例对象:

 

                                                     boolean、byte、char、short、int、long、float、double、void

 

 

反射

 

          反射就是把 Java 类中的各种成分映射成相应的 Java 类。例如,一个 Java 类中用一个 Class 类的对象来表示,一个类中的组成部分:成员变量、方法、构造方法、包等等信息也用一个个 Java 类来表示。表示 Java 类的 Class 类显然要提供一系列的方法,来过的其中的变量、方法、构造方法、修饰符、包等信息,这些信息就是用相应类的实例对象来表示,它们是 Field、Method、Constructor、Package 等等。一个类中的每个成员都可以用相应的反射 API 类的一个实例对象来表示,通过调用 Class 类的方法可以得到这些实例对象。

 

 

Constructor 类

 

          一个 Constroctor 类代表一个字节码中的一个构造方法。

 

           (1)得到一个类中的所有构造方法。例如:Constroctor[] constroctors = Class.forName("java.lang.String").getConstroctors();

 

           (2)得到一个类中的某一个构造方法。例如:Constroctor constroctor = Class.forName("java.lang.String").getConstroctor(StringBuffer.class);

 

            编程实例:用反射的方式创建一个类的实例对象

 

           

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         // 1   
  4.         Constructor constructor = String.class  
  5.                 .getConstructor(StringBuffer.class);  
  6.         String string = (String) constructor.newInstance(new StringBuffer(  
  7.                 "DriverKing_斌"));  
  8.         System.out.println(string);  
  9.         // 2 这种方法是用字节码直接创建一个对象,用的是无参的构造函数   
  10.         String s = String.class.newInstance();  
  11.     }  
  12. }  

 

 

Field 类

 

 

              Field 类代表某个类中的一个成员变量。因为 Field 是对应到对象上面的成员变量,所以 Field 代表的成员变量是具体的,不是抽象的,一个类的字节码对应着一个类的成员变量。

 

              编程实例: 用反射的方式获取一个类中的成员变量,并修改变量的值

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         B b = new B("DriverKing""男"23);  
  4.         Field fName = b.getClass().getDeclaredField("name"); // 通过B类的字节码根据字段名来获取字段对象,如果字段是对外公开的就用getField("");   
  5.         fName.setAccessible(true); // 因为 name字段是私有的,则必须设置setAccessible(true),才能进行修改,俗称暴力反射,哈哈,犀利   
  6.         String oldName = (String) fName.get(b); // 通过字段的对象来获取B的实例对象的字段值   
  7.         System.out.println("原名:" + oldName);  
  8.         fName.set(b, "DriverKing_斌");  
  9.         String newName = (String) fName.get(b);  
  10.         System.out.println("改后:" +newName);  
  11.     }  
  12. }  
  13. class B {  
  14.     public B(String name, String sex, int age) {  
  15.         this.setName(name);  
  16.         this.setSex(sex);  
  17.         this.setAge(age);  
  18.     }  
  19.     private String name;  
  20.     private String sex;  
  21.     private int age;  
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.     public void setName(String name) {  
  26.         this.name = name;  
  27.     }  
  28.     public String getSex() {  
  29.         return sex;  
  30.     }  
  31.     public void setSex(String sex) {  
  32.         this.sex = sex;  
  33.     }  
  34.     public int getAge() {  
  35.         return age;  
  36.     }  
  37.     public void setAge(int age) {  
  38.         this.age = age;  
  39.     }  
  40. }  

 

           运行结果:

 

           原名:DriverKing
           改后:DriverKing_斌

 

           编程实例:将任意一个对象中的所有 String 类型的成员变量所对应的字符串内容中的 “b” 改为 “a”

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         B b = new B("black""hubei""basketball"23);  
  4.         System.out.println(b);  
  5.         Field[] fields = b.getClass().getDeclaredFields();  
  6.         for (int i = 0; i < fields.length; i++) {  
  7.             if (fields[i].getType() == String.class) {  
  8.                 fields[i].setAccessible(true);  
  9.                 String oldString = (String) fields[i].get(b);  
  10.                 String newString = oldString.replace('b''a');  
  11.                 fields[i].set(b, newString);  
  12.             }  
  13.         }  
  14.         System.out.println(b);  
  15.     }  
  16. }  
  17. class B {  
  18.     private String name;  
  19.     private String address;  
  20.     private String hobby;  
  21.     private int age;  
  22.     public B(String name, String address, String hobby, int age) {  
  23.         super();  
  24.         this.name = name;  
  25.         this.address = address;  
  26.         this.hobby = hobby;  
  27.         this.age = age;  
  28.     }  
  29.     public String getName() {  
  30.         return name;  
  31.     }  
  32.     public void setName(String name) {  
  33.         this.name = name;  
  34.     }  
  35.     public String getAddress() {  
  36.         return address;  
  37.     }  
  38.     public void setAddress(String address) {  
  39.         this.address = address;  
  40.     }  
  41.     public String getHobby() {  
  42.         return hobby;  
  43.     }  
  44.     public void setHobby(String hobby) {  
  45.         this.hobby = hobby;  
  46.     }  
  47.     public int getAge() {  
  48.         return age;  
  49.     }  
  50.     public void setAge(int age) {  
  51.         this.age = age;  
  52.     }  
  53.     public String toString() {  
  54.         return name + "," + address + "," + hobby + "," + age;  
  55.     }  
  56. }  

 

           运行结果:

 

           black,hubei,basketball,23
           alack,huaei,aasketaall,23

 

 

 Method 类

 

         Method 类代表某个类中的一个成员方法。

 

          (1)得到类中的某一个方法。例如:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);

 

          (2)调用方法。例:System.out.println(charAt.invoke(str,2));  // 普通方式调用: System.out.println(str.charAt(2));

 

           编程实例:用反射的方式调用某个类的方法

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Method method = String.class.getMethod("charAt"int.class);  
  4.         System.out.println(method.invoke(new String("abc"), 2));  
  5.     }  
  6. }  

 

          (3)用反射的方式执行某个类的 main 方法

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Method method = Class.forName(args[0]).getMethod("main", String[].class);// 获取 main方法   
  4.         // jdk1.4没有可变参,它会将字符串数组拆开作为参数来用,而拆开后,又不是字符串数组了,   
  5.         // 而是字符串了,所以jdk1.5为了兼容jdk1.4必须将字符串数组看为一个单独的对象,告诉编译器   
  6.         method.invoke(null, (Object) new String[] { "a""b" });  
  7.     }  
  8. }  
  9. class B {  
  10.     public static void main(String[] args) {  
  11.         System.out.println(args[1]);  
  12.     }  
  13. }  

 

          (4)对数组的反射

 

                 具有相同维数和元素类型的数组属于同一个类型,即代表有相同的 Class 实例对象。相同的维数,例如:二维数组就是数组的数组,也就是说数组里面存放的是引用类型的对象,它的字节码就不相同。所以 具有相同维数和元素类型的数组才是属于同一个类型。如果想获得一个数组的类型用:Class 实例对象的 getSuperClass()

 

          编程实例:用反射的方法打印数组

 

         

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         int[] array = {1,123,45,4,34,67};  
  4.         printObject(array);  
  5.     }  
  6.     private static void printObject(Object obj) {  
  7.         Class objClass = obj.getClass();  
  8.         if (objClass.isArray()) {  
  9.             int len = Array.getLength(obj);  
  10.             for (int i = 0; i < len; i++) {  
  11.                 System.out.println(Array.get(obj, i));  
  12.             }  
  13.         } else  
  14.             System.out.println(obj);  
  15.     }  
  16. }  

 

 

         (5)对集合的反射

 

          编程实例:利用配置文件指定集合的类型,然后再用反射创建集合并打印集合

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         InputStream in = new FileInputStream("config.properties");  
  4.         Properties properties = new Properties();  
  5.         properties.load(in);  
  6.         String className = properties.getProperty("className");  
  7.         Collection c = (Collection) Class.forName(className).newInstance();  
  8.         c.add("a");  
  9.         c.add("b");  
  10.         c.add("c");  
  11.         printObject(c);  
  12.     }  
  13.     private static void printObject(Object obj) {  
  14.         Class objClass = obj.getClass();  
  15.         if (objClass.isArray()) {  
  16.             int len = Array.getLength(obj);  
  17.             for (int i = 0; i < len; i++) {  
  18.                 System.out.println(Array.get(obj, i));  
  19.             }  
  20.         } else  
  21.             System.out.println(obj);  
  22.     }  
  23. }  

 

 

        (6)用类加载器加载配置文件

 

          

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class A {  
  2.     public static void main(String[] args) throws Exception {  
  3.         // InputStream in = new FileInputStream("config.properties");   
  4.         //InputStream in = A.class.getClassLoader().getResourceAsStream("config.properties");   
  5.         InputStream in = A.class.getResourceAsStream("config.properties");  
  6.         Properties properties = new Properties();  
  7.         properties.load(in);  
  8.         String className = properties.getProperty("className");  
  9.         Collection c = (Collection) Class.forName(className).newInstance();  
  10.         c.add("a");  
  11.         c.add("b");  
  12.         c.add("c");  
  13.         printObject(c);  
  14.           
  15.     }  
  16.     private static void printObject(Object obj) {  
  17.         Class objClass = obj.getClass();  
  18.         if (objClass.isArray()) {  
  19.             int len = Array.getLength(obj);  
  20.             for (int i = 0; i < len; i++) {  
  21.                 System.out.println(Array.get(obj, i));  
  22.             }  
  23.         } else  
  24.             System.out.println(obj);  
  25.     }  
  26. }  

 

原创粉丝点击