一、JAVA是動態(tài)語言嗎?
一般而言,說到動態(tài)言,都是指在程序運行時允許改變程序結(jié)構(gòu)或者變量類型,從這個觀點看,Java和C++一樣,都不是動態(tài)語言。
但JAVA它卻有著一個非常突出的動態(tài)相關(guān)機制:反射。通過反射,Java可以于運行時加載、探知和使用編譯期間完全求和的類、生成其對象實體,調(diào)用其方法或者對屬性設(shè)值。所以Java算是一個半動態(tài)的語言吧。
反射的概念:
在Java中的反射機制是指在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;
對于任意一個對象,都能夠調(diào)用它的任意一個方法;
這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為Java語言的反射機制
二、動態(tài)性質(zhì)
2.1、動態(tài)性質(zhì)
運行時生成對象實例;
運行期間調(diào)用方法;
運行時更改屬性
2.2、Java反射機制能實現(xiàn)的功能
在運行時判斷任意一個對象所屬的類
在運行時構(gòu)造任意一個類的對象
在運行時判斷任意懷個類所具有的方法和屬性
在運行時調(diào)用任意一個對象的方法
生成動態(tài)代理
2.3、Java反射應(yīng)用場合
在Java程序中許多對象在運行時都會出現(xiàn)兩種類型:編譯時類型和運行時類型
編譯時的類型由聲明該對象時使用的類型決定,運行時的類型由實際賦給對象的類型決定
如:
1
|
Person p = new Student(); |
編譯時類型為Person,而運行時為Student
除此之外,程序在運行時還可能接收到外部傳入的一個對象,該對象的編譯時類型為Object,但程序又需要調(diào)用該對象運行時類型的方法。為了這些問題程序需要在運行時發(fā)現(xiàn)對象和類的真實信息。然而,如果編譯時根本無法預(yù)知該對象和類可能屬于哪些類,程序只依靠運行時信息來發(fā)現(xiàn)該對象和類的真實信息,此時就必須使用反射
三、Java反射API
反射API用來生成在當前JAVA虛擬機中的類、接口或者對象的信息。
Class類:反射的核心類,可以獲取類的屬性,方法等內(nèi)容信息。
Field類:Java.lang.reflect.表示類的屬性,可以獲取和設(shè)置類的中屬性值。
Method類:Java.lang.reflect。表示類的方法,它可以用來獲取類中方法的信息或者執(zhí)行方法
Construcor類:Java.lang.reflect。表示類的構(gòu)造方法。
四、獲取全部方法和屬性
Person類
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
|
package com.pb.Reflect.classinfo; public class Person { private String name; private String gender; private int age; private Person() { // } public Person(String name, String gender, int age) { super (); this .name = name; this .gender = gender; this .age = age; } //getter、和setter方法 private String getName() { return name; } private void setName(String name) { this .name = name; } public String getGender() { return gender; } public void setGender(String gender) { this .gender = gender; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String toString(){ return "姓名:" +name+ "年齡: " +age; } } |
使用反射:
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
|
package com.pb.Reflect.classinfo; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import javax.swing.JOptionPane; /* * 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性 * Declared獲取全部不管是私有和公有 * 1.獲取訪問類的Class對象 * 2.調(diào)用Class對象的方法返回訪問類的方法和屬性信息 */ public class ReflectDemo { /* * 構(gòu)造方法 */ public ReflectDemo(){ //用戶輸入類的全路徑徑 //使用String組件 String classpsth=JOptionPane.showInputDialog( null , "輸入類的全路徑" ); //使用Class.forName方法根據(jù)輸入的類的全路徑 返回該類的Class對象 try { Class cla = Class.forName(classpsth); //利用Class對象的cla的自審,返回方法對象集合 Method [] method=cla.getDeclaredMethods(); //返回所有的方法 System.out.println( "========獲取方法信息============" ); for (Method meth : method) { //遍歷method數(shù)組,并輸出方法信息 System.out.println(meth.toString()); } System.out.println( "========獲取出方法信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合 Field [] field=cla.getDeclaredFields(); System.out.println( "========獲取成員屬性信息============" ); for (Field f : field) { System.out.println(f.toString()); } System.out.println( "========獲取成員屬性信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回構(gòu)造方法集合 Constructor [] constructor=cla.getDeclaredConstructors(); System.out.println( "========獲取成員構(gòu)造方法信息============" ); for (Constructor constru : constructor) { System.out.println(constru.toString()); } System.out.println( "========獲取成員構(gòu)造方法信息結(jié)束============" ); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println( "路徑輸入錯誤!" ); } } } |
1
2
3
4
5
6
7
8
9
10
|
package com.pb.Reflect.classinfo; public class TestReflection { public static void main(String[] args) { ReflectDemo rd= new ReflectDemo(); } } |
輸入com.pb.Reflect.classinfo.Person
結(jié)果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge( int ) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取構(gòu)造方法信息============ private com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String, int ) ========獲取構(gòu)造方法信息結(jié)束============ |
五、使用反射的步驟
5.1、步驟
Java.lang.reflect
獲得想操作類的Java.lang.Class對象
調(diào)用Class的方法
使用反射API來操作這些信息
5.2、獲取Class對象方式
調(diào)用某個對象的getClass()方法
1
2
|
Person p = new Person(); Class cla=p.getClass(); |
調(diào)用某個類的class屬性來獲取該類對應(yīng)的Class對象
1
|
Class cls=Person. class ; |
使用Class類的forName()靜態(tài)方法
1
|
Class cla=Class.forName(“類的全路徑”); |
六、第二種方式對象的getClass()方法
Person類,因為要聲明對象所以將構(gòu)造方法public
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
|
package com.pb.Reflect.classinfo; public class Person { private String name; private String gender; private int age; public Person() { // } public Person(String name, String gender, int age) { super (); this .name = name; this .gender = gender; this .age = age; } //getter、和setter方法 private String getName() { return name; } private void setName(String name) { this .name = name; } public String getGender() { return gender; } public void setGender(String gender) { this .gender = gender; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String toString(){ return "姓名:" +name+ "年齡: " +age; } } |
使用反射:
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
|
package com.pb.Reflect.classinfo; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import javax.swing.JOptionPane; /* * 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性 * Declared獲取全部不管是私有和公有 * 1.獲取訪問類的Class對象 * 2.調(diào)用Class對象的方法返回訪問類的方法和屬性信息 */ public ReflectDemo(Person p){ Class cla=p.getClass(); //利用Class對象的cla的自審,返回方法對象集合 Method [] method=cla.getDeclaredMethods(); //返回所有的方法 System.out.println( "========獲取方法信息============" ); for (Method meth : method) { //遍歷method數(shù)組,并輸出方法信息 System.out.println(meth.toString()); } System.out.println( "========獲取出方法信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合 Field [] field=cla.getDeclaredFields(); System.out.println( "========獲取成員屬性信息============" ); for (Field f : field) { System.out.println(f.toString()); } System.out.println( "========獲取成員屬性信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回構(gòu)造方法集合 Constructor [] constructor=cla.getDeclaredConstructors(); System.out.println( "========獲取成員構(gòu)造方法信息============" ); for (Constructor constru : constructor) { System.out.println(constru.toString()); } System.out.println( "========獲取成員構(gòu)造方法信息結(jié)束============" ); } } |
測試類
1
2
3
4
5
6
7
8
9
10
11
|
package com.pb.Reflect.classinfo; public class TestReflection { public static void main(String[] args) { Person p= new Person(); ReflectDemo rd= new ReflectDemo(p); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge( int ) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取成員構(gòu)造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String, int ) ========獲取成員構(gòu)造方法信息結(jié)束============ |
七、第三種方法類的.class屬性
Person類同上
測試類:
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
|
package com.pb.Reflect.classinfo; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class TestReflection { public static void main(String[] args) { /*第二種方法 Person p=new Person(); ReflectDemo rd=new ReflectDemo(p); */ /* * 第三種方式.class屬性 */ Class cla=Person. class ; //利用Class對象的cla的自審,返回方法對象集合 Method [] method=cla.getDeclaredMethods(); //返回所有的方法 System.out.println( "========獲取方法信息============" ); for (Method meth : method) { //遍歷method數(shù)組,并輸出方法信息 System.out.println(meth.toString()); } System.out.println( "========獲取出方法信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合 Field [] field=cla.getDeclaredFields(); System.out.println( "========獲取成員屬性信息============" ); for (Field f : field) { System.out.println(f.toString()); } System.out.println( "========獲取成員屬性信息結(jié)束============" ); //獲取屬性利用Class對象的cla的自審,返回構(gòu)造方法集合 Constructor [] constructor=cla.getDeclaredConstructors(); System.out.println( "========獲取成員構(gòu)造方法信息============" ); for (Constructor constru : constructor) { System.out.println(constru.toString()); } System.out.println( "========獲取成員構(gòu)造方法信息結(jié)束============" ); } } |
結(jié)果:
同上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge( int ) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取成員構(gòu)造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String, int ) ========獲取成員構(gòu)造方法信息結(jié)束============ |
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://blog.csdn.net/qq_37267015/article/details/77365933