反射(得到Class類的幾種方式)


目錄:

1)java反射機制概述

2)理解Class類並獲取Class實例

3)類的加載與ClassLoader

4)創建運行時類的對象

5)獲取運行時類的完整結構

6)調用運行時類的指定結構

 

一---基本概念

  Java的反射(reflection)機制是指在程序的運行狀態中,可以構造任意一個類的對象,可以了解任意一個對象所屬的類,可以了解任意一個類的成員變量和方法(即使是private的),可以調用任意一個對象的屬性和方法。這種動態獲取程序信息以及動態調用對象的功能稱為Java語言的反射機制。反射被視為動態語言的關鍵(來自 百度百科)。

一句話概述就是利用反射,底褲都能扒出來。

游戲外掛的原理:游戲在運行的時候,通過反射去改變運行時的參數,從而達到作弊的目的。

正常方式:引入需要的包類名稱->通過new實例化->取得實例化對象

反射方式:實例化對象->getClass()方法->得到完整的包類名稱

加載完類之后,在堆內存的方法區中就產生了一個Class類型的對象,通過這個對象我們可以看到類的結構。

 1 package reflection;
 2 
 3 
 4 public class test01 extends Object{
 5     public static void main(String[] args) throws ClassNotFoundException{
 6         // 通過反射獲取類的class對象
 7         Class c1 = Class.forName("reflection.user");
 8         System.out.println(c1);
 9         Class c2 = Class.forName("reflection.user");
10         Class c3 = Class.forName("reflection.user");
11         Class c4 = Class.forName("reflection.user");
12 
13         //  一個類在內存中只有一個class對象
14         // 一個類被加載后,類的整個結構都會被封裝在class對象中
15         System.out.println(c2.hashCode());
16         System.out.println(c3.hashCode());
17         System.out.println(c4.hashCode());
18 
19     }
20 }
21 
22 // 實體類
23 class user {
24     private String name;
25     private  int id;
26     private  int age;
27 
28     public user() {
29     }
30 
31     public user(String name, int id, int age) {
32         this.name = name;
33         this.id = id;
34         this.age = age;
35     }
36 
37     public String getName() {
38         return name;
39     }
40 
41     public void setName(String name) {
42         this.name = name;
43     }
44 
45     public int getId() {
46         return id;
47     }
48 
49     public void setId(int id) {
50         this.id = id;
51     }
52 
53     public int getAge() {
54         return age;
55     }
56 
57     public void setAge(int age) {
58         this.age = age;
59     }
60 
61     @Override
62     public String toString() {
63         return "user{" +
64                 "name='" + name + '\'' +
65                 ", id=" + id +
66                 ", age=" + age +
67                 '}';
68     }
69 }

運行結果:無論創建多少個對象,Class的類型都只有一個

 

 

 

反射的優缺點

1)優點:可以動態創建對象和編譯,靈活性大

2)缺點:對性能有影響,我們告訴虛擬機我們要做什么,讓他去干,命令下達和他完成完有一個時間延遲。直接new出來的和反射出來的差了好幾十倍。

反射主要的API:

1)java.lang.Class:代表一個類  (記住這個)

2)java.lang.reflect.Method: 代表類的方法

3)java.lang.reflect.Field:代表類的成員變量

4)java.lang.reflect.Constructor:代表類的構造器

 

Class類:

在Object類中定義了以下的方法,此方法將被所有子類繼承

1 public final native Class getClass();

 

1)Class本身也是一個類

2)Class對象只能由系統建立對象

3)一個加載的類在JVM中只會有一個Class實例

4)一個Class對象對應的是一個加載到JVM中的一個class文件

5)每個類的實例都會記得自己是由哪個Class實例所生成

6)通過Class可以完整的得到一個類中的所有被加載的結構

7)Class是reflection的根源,針對任何你想動態加載,運行的類,唯有先獲得相應的Class對象

Class類的常用方法:

 

 獲取Class類的實例:

1)若已知具體的類,通過類的class屬性獲取,該方法最為安全可靠,程序性能最高

Class clazz = Person.class

2)已知某個類的實例,調用該實例的getClass()方法獲取Class()對象

Class clazz = person.getClass()

3)已知一個類的全類名,且該類在類路徑下,可通過Class類的靜態方法forName()獲取,

可能拋出ClassNotFoundException

class clazz = Class.forName("demo01.Studengt")

4)內置基本數據類型可以 直接用類名.Type

測試代碼:

 1 package reflection;
 2 
 3 public class test02 {
 4     public static void main(String[] args) throws ClassNotFoundException {
 5         Person person = new Student();
 6         System.out.println("這個人是" + person.name);
 7         // 方式一: 通過對象獲得
 8         Class c1 = person.getClass();
 9         System.out.println(c1.hashCode());
10 
11 
12         // 方式二: forName獲得
13         Class c2 = Class.forName("reflection.Student");
14         System.out.println(c2.hashCode());
15 
16         // 方式三: 通過類名.class獲得
17         Class c3 = Student.class;
18         System.out.println(c3.hashCode());
19 
20         // 方式四: 基本內置類型的包裝類都有一個Type屬性
21         Class c4 = Float.TYPE;
22         System.out.println(c4);
23 
24         // 獲得父類的類型(這里就是通過對象獲取類)
25         Class c5 = c1.getSuperclass();
26         System.out.println(c5);
27         
28     }
29 }
30 
31 class Person {
32      String name;
33      int age;
34 
35     public Person() {
36     }
37 
38     public Person(String name, int age) {
39         this.name = name;
40         this.age = age;
41     }
42 
43 }
44 
45 class Student extends Person {
46     public Student() {
47         this.name = "學生";
48     }
49 }
50 
51 class Teacher extends Person {
52     public Teacher() {
53         this.name = "老師";
54     }
55 }

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM