1. 程式人生 > >java反射詳解--三分鐘學會使用java反射

java反射詳解--三分鐘學會使用java反射

本篇文章依舊採用小例子來說明,因為我始終覺的,案例驅動是最好的,要不然只看理論的話,看了也不懂,不過建議大家在看完文章之後,在回過頭去看看理論,會有更好的理解。

下面開始正文。

【案例1】通過一個物件獲得完整的包名和類名

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /** * 通過一個物件獲得完整的包名和類名 * */ class Demo{ //other codes...
} class hello{ public static void main(String[] args) { Demo demo=new Demo(); System.out.println(demo.getClass().getName()); } }

【執行結果】:Reflect.Demo

新增一句:所有類的物件其實都是Class的例項。

【案例2】例項化Class類物件

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Reflect; class Demo{ //other codes... } class hello{ public static void main(String[] args) { Class<?> demo1=null; Class<?> demo2=null; Class<?> demo3=null; try{ //一般儘量採用這種形式 demo1=Class.forName("Reflect.Demo"); }catch(Exception e){ e.printStackTrace();
} demo2=new Demo().getClass(); demo3=Demo.class; System.out.println("類名稱   "+demo1.getName()); System.out.println("類名稱   "+demo2.getName()); System.out.println("類名稱   "+demo3.getName()); } }

【執行結果】:

類名稱   Reflect.Demo

類名稱   Reflect.Demo

類名稱   Reflect.Demo

【案例3】通過Class例項化其他類的物件

通過無參構造例項化物件

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package Reflect; class Person{ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString(){ return "["+this.name+"  "+this.age+"]"; } private String name; private int age; } class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Person per=null; try { per=(Person)demo.newInstance(); catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } per.setName("Rollen"); per.setAge(20); System.out.println(per); } }

【執行結果】:

[Rollen  20]

但是注意一下,當我們把Person中的預設的無參建構函式取消的時候,比如自己定義只定義一個有引數的建構函式之後,會出現錯誤:

比如我定義了一個建構函式:

1 2 3 4 public Person(String name, int age) { this.age=age; this.name=name; }

然後繼續執行上面的程式,會出現:

java.lang.InstantiationException: Reflect.Person

    at java.lang.Class.newInstance0(Class.java:340)

    at java.lang.Class.newInstance(Class.java:308)

    at Reflect.hello.main(hello.java:39)

Exception in thread "main" java.lang.NullPointerException

    at Reflect.hello.main(hello.java:47)

所以大家以後再編寫使用Class例項化其他類的物件的時候,一定要自己定義無參的建構函式

【案例】通過Class呼叫其他類中的建構函式(也可以通過這種方式通過Class建立其他類的物件)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package Reflect; import java.lang.reflect.Constructor; class Person{ public Person() { } public Person(String name){ this