java反射详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 .name=name; } public Person( int age){ this .age=age; } public Person(String name, int age) { this .age=age; this .name=name; } public String getName() { return name; } public int getAge() { return 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 per1= null ; Person per2= null ; Person per3= null ; Person per4= null ; //取得全部的构造函数 Constructor<?> cons[]=demo.getConstructors(); try { per1=(Person)cons[ 0 ].newInstance(); per2=(Person)cons[ 1 ].newInstance( "Rollen" ); per3=(Person)cons[ 2 ].newInstance( 20 ); per4=(Person)cons[ 3 ].newInstance( "Rollen" , 20 ); } catch (Exception e){ e.printStackTrace(); } System.out.println(per1); System.out.println(per2); System.out.println(per3); System.out.println(per4); } } |
【运行结果】:
[null 0]
[Rollen 0]
[null 20]
[Rollen 20]
【案例】
返回一个类实现的接口:
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
|
package Reflect; interface China{ public static final String name= "Rollen" ; public static int age= 20 ; public void sayChina(); public void sayHello(String name, int age); } class Person implements China{ public Person() { } public Person(String sex){ this .sex=sex; } public String getSex() { return sex; } public void setSex(String sex) { this .sex = sex; } @Override public void sayChina(){ System.out.println( "hello ,china" ); } @Override public void sayHello(String name, int age){ System.out.println(name+ " " +age); } private String sex; } class hello{ public static void main(String[] args) { Class<?> demo= null ; try { demo=Class.forName( "Reflect.Person" ); } catch (Exception e) { e.printStackTrace(); } //保存所有的接口 Class<?> intes[]=demo.getInterfaces(); for ( int i = 0 ; i < intes.length; i++) { System.out.println( "实现的接口 " +intes[i].getName()); } } } |
【运行结果】:
实现的接口 Reflect.China
(注意,以下几个例子,都会用到这个例子的Person类,所以为节省篇幅,此处不再粘贴Person的代码部分,只粘贴主类hello的代码)
【案例】:取得其他类中的父类
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class hello{ public static void main(String[] args) { Class<?> demo= null ; try { demo=Class.forName( "Reflect.Person" ); } catch (Exception e) { e.printStackTrace(); } //取得父类 Class<?> temp=demo.getSuperclass(); System.out.println( "继承的父类为: " +temp.getName()); } } |
【运行结果】
继承的父类为: java.lang.Object
【案例】:获得其他类中的全部构造函数
这个例子需要在程序开头添加import java.lang.reflect.*;
然后将主类编写为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class hello{ public static void main(String[] args) { Class<?> demo= null ; try { demo=Class.forName( "Reflect.Person" ); } catch (Exception e) { e.printStackTrace(); } Constructor<?>cons[]=demo.getConstructors(); for ( int i = 0 ; i < cons.length; i++) { System.out.println( "构造方法: " +cons[i]); } } } |
【运行结果】:
构造方法: public Reflect.Person()
构造方法: public Reflect.Person(java.lang.String)
但是细心的读者会发现,上面的构造函数没有public 或者private这一类的修饰符
下面这个例子我们就来获取修饰符
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
|
class hello{ public static void main(String[] args) { Class<?> demo= null ; try { demo=Class.forName( "Reflect.Person" ); } catch (Exception e) { e.printStackTrace(); } Constructor<?>cons[]=demo.getConstructors(); for ( int i = 0 ; i < cons.length; i++) { Class<?> p[]=cons[i].getParameterTypes(); System.out.print( "构造方法: " ); int mo=cons[i].getModifiers(); System.out.print(Modifier.toString(mo)+ " " ); System.out.print(cons[i].getName()); &nb |