码迷,mamicode.com
首页 > 编程语言 > 详细

5、java反射基础

时间:2016-04-14 20:54:36      阅读:324      评论:0      收藏:0      [点我收藏+]

标签:

 

Class对象:

Class对象记录了所有与类相关的信息,当类加载器从文件系统中加载.class文件到JVM中的同时会为每一个类创建一个Class对象。通过Class对象可以获取到类的属性、方法、构造器等全部与类相关的信息。

 

现在假设在com.aop包下有一个抽象类和一个类,定义如下:

package com.aop;

abstract public class Creature<T> {

}
 1 package com.aop;
 2 
 3 public class Person extends Creature<String>{
 4 
 5     int id;
 6     public String name;
 7     private int age;
 8     
 9     public Person() { }
10     public Person(int age, String name){
11         this.age = age;
12         this.name = name;
13     }
14 
15     public int getId() {
16         return id;
17     }
18 
19     public void setId(int id) {
20         this.id = id;
21     }
22 
23     public String getName() {
24         return name;
25     }
26 
27     public int getAge() {
28         return age;
29     }
30 
31     public void setName(String name) {
32         this.name = name;
33     }
34 
35     public void setAge(int age) {
36         this.age = age;
37     }
38     
39     static public void countAdd(int a, Integer b){
40         System.out.println(a + " + " + b + " = " + (a+b));
41     }
42 
43     public void show() {
44         System.out.println("我是一个人!");
45     }
46 
47     public void display(String nation) {
48         System.out.println("我的国际是:" + nation);
49     }
50 
51     @Override
52     public String toString() {
53         return "Person [name=" + name + ", age=" + age + "]";
54     }
55 
56 }

很简洁,定义一个带泛型的抽象类,Person继承自该抽象类。

 

与反射相关的包:

import java.lang.reflect.Constructor;  //与构造器相关
import java.lang.reflect.Field;      //与域相关
import java.lang.reflect.Method;      //与方法相关

//还有其它的...

 

1、Class对象的4中获取方式:

 1 package com.aop;
 2 
 3 import org.junit.Test;
 4 
 5 public class TestReflection {
 6     
 7     @Test
 8     public void testReflection() throws Exception{
 9         
10         //1.调用运行时类本身的.class属性
11         Class<Person> clazz1 = Person.class;
12         
13         //2.通过运行时类的对象获取
14         Person person = new Person();
15         Class<? extends Person> clazz2 = person.getClass();
16         
17         //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
18         String className = "com.aop.Person";
19         
20         Class<?> clazz3 = Class.forName(className);
21         
22         //4.(了解)通过类的加载器
23         ClassLoader loader = this.getClass().getClassLoader();
24         Class<?> clazz4 = loader.loadClass(className);
25         
26         System.out.println(clazz1.getName());
27         System.out.println(clazz2.getName());
28         System.out.println(clazz3.getName());
29         System.out.println(clazz4.getName());
30         
31         System.out.println(clazz1 == clazz2);
32         System.out.println(clazz1 == clazz3);
33         System.out.println(clazz1 == clazz4);
34     }
35 }

 

 

2、通过反射读取对象的属性值,并修改它们(能够读取与修改包括private权限的属性值

 1 @Test
 2     public void testField() throws Exception{
 3         String className = "com.aop.Person";
 4         Class<?> clazz = Class.forName(className);
 5         
 6         Person person = (Person) clazz.newInstance();
 7         
 8         //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
 9         Field field = clazz.getField("name");
10         field.set(person, "东东");
11         System.out.println(person);
12         
13         //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
14         Field field2 = clazz.getDeclaredField("age");
15         //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
16         field2.setAccessible(true);    
17         field2.set(person, 100);
18         System.out.println(person);
19         
20     }

 

 

3、通过反射调用对象的方法

 1 @Test
 2     public void testMethod() throws Exception{
 3         String className = "com.aop.Person";
 4         Class<?> clazz = Class.forName(className);
 5         
 6         Person person = new Person(50, "哈哈");
 7         
 8         //获取并调用无参的show方法
 9         Method method1 = clazz.getMethod("show");
10         method1.invoke(person);
11         
12         //获取并调用有参的display方法
13         Method method2 = clazz.getMethod("display", String.class);
14         method2.invoke(person, "中国");
15         
16         //调用有返回值的方法
17         Method method3 = clazz.getMethod("toString");
18         Object resultVal = method3.invoke(person);
19         System.out.println(resultVal);
20         
21         //调用有参数的静态方法
22         Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
23         method4.invoke(Person.class, 10, 100);
24     }

 

 

4、通过反射调用带参构造器来实例化一个对象

 1     @Test
 2     public void testConstructor() throws Exception{
 3         String className = "com.aop.Person";
 4         Class<?> clazz = Class.forName(className);
 5         
 6         //调用一个有参的构造器
 7         Constructor<?> cons = clazz.getConstructor(int.class, String.class);
 8         Person person = (Person) cons.newInstance(20, "兮兮");
 9         System.out.println(person);
10     }

 

 

5、获取“父类”、“带泛型的父类”、“父类的泛型

 1 @Test
 2     public void testGeneric() throws Exception{
 3         String className = "com.aop.Person";
 4         Class<?> clazz = Class.forName(className);
 5         
 6         //1、获取父类,只能得到父类的名称
 7         Class<?> superClazz = clazz.getSuperclass();
 8         System.out.println(superClazz);
 9         
10         //2、获取带泛型的父类
11         Type type = clazz.getGenericSuperclass();
12         System.out.println(type);
13         
14         //3、获取父类的泛型类(重要)
15         ParameterizedType param = (ParameterizedType)type;
16         Type[] argmts = param.getActualTypeArguments();
17         Class<?> claz = (Class<?>)argmts[0];
18         System.out.println(claz);
19     }

 

 

下面是全部的源代码:

技术分享
1 package com.aop;
2 
3 abstract public class Creature<T> {
4 
5 }
abstract public class Creature
技术分享
 1 package com.aop;
 2 
 3 public class Person extends Creature<String>{
 4 
 5     int id;
 6     public String name;
 7     private int age;
 8     
 9     public Person() { }
10     public Person(int age, String name){
11         this.age = age;
12         this.name = name;
13     }
14 
15     public int getId() {
16         return id;
17     }
18 
19     public void setId(int id) {
20         this.id = id;
21     }
22 
23     public String getName() {
24         return name;
25     }
26 
27     public int getAge() {
28         return age;
29     }
30 
31     public void setName(String name) {
32         this.name = name;
33     }
34 
35     public void setAge(int age) {
36         this.age = age;
37     }
38     
39     static public void countAdd(int a, Integer b){
40         System.out.println(a + " + " + b + " = " + (a+b));
41     }
42 
43     public void show() {
44         System.out.println("我是一个人!");
45     }
46 
47     public void display(String nation) {
48         System.out.println("我的国际是:" + nation);
49     }
50 
51     @Override
52     public String toString() {
53         return "Person [name=" + name + ", age=" + age + "]";
54     }
55 
56 }
public class Person extends Creature
技术分享
  1 package com.aop;
  2 
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.Method;
  6 import java.lang.reflect.ParameterizedType;
  7 import java.lang.reflect.Type;
  8 
  9 import org.junit.Test;
 10 
 11 public class TestReflection {
 12     
 13     @Test
 14     public void testReflection() throws Exception{
 15         
 16         //1.调用运行时类本身的.class属性
 17         Class<Person> clazz1 = Person.class;
 18         
 19         //2.通过运行时类的对象获取
 20         Person person = new Person();
 21         Class<? extends Person> clazz2 = person.getClass();
 22         
 23         //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
 24         String className = "com.aop.Person";
 25         
 26         Class<?> clazz3 = Class.forName(className);
 27         
 28         //4.(了解)通过类的加载器
 29         ClassLoader loader = this.getClass().getClassLoader();
 30         Class<?> clazz4 = loader.loadClass(className);
 31         
 32         System.out.println(clazz1.getName());
 33         System.out.println(clazz2.getName());
 34         System.out.println(clazz3.getName());
 35         System.out.println(clazz4.getName());
 36         
 37         System.out.println(clazz1 == clazz2);
 38         System.out.println(clazz1 == clazz3);
 39         System.out.println(clazz1 == clazz4);
 40     }
 41     
 42     @Test
 43     public void testField() throws Exception{
 44         String className = "com.aop.Person";
 45         Class<?> clazz = Class.forName(className);
 46         
 47         Person person = (Person) clazz.newInstance();
 48         
 49         //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
 50         Field field = clazz.getField("name");
 51         field.set(person, "东东");
 52         System.out.println(person);
 53         
 54         //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
 55         Field field2 = clazz.getDeclaredField("age");
 56         //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
 57         field2.setAccessible(true);    
 58         field2.set(person, 100);
 59         System.out.println(person);
 60         
 61     }
 62     
 63     @Test
 64     public void testMethod() throws Exception{
 65         String className = "com.aop.Person";
 66         Class<?> clazz = Class.forName(className);
 67         
 68         Person person = new Person(50, "哈哈");
 69         
 70         //获取并调用无参的show方法
 71         Method method1 = clazz.getMethod("show");
 72         method1.invoke(person);
 73         
 74         //获取并调用有参的display方法
 75         Method method2 = clazz.getMethod("display", String.class);
 76         method2.invoke(person, "中国");
 77         
 78         //调用有返回值的方法
 79         Method method3 = clazz.getMethod("toString");
 80         Object resultVal = method3.invoke(person);
 81         System.out.println(resultVal);
 82         
 83         //调用有参数的静态方法
 84         Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
 85         method4.invoke(Person.class, 10, 100);
 86     }
 87     
 88     @Test
 89     public void testConstructor() throws Exception{
 90         String className = "com.aop.Person";
 91         Class<?> clazz = Class.forName(className);
 92         
 93         //调用一个有参的构造器
 94         Constructor<?> cons = clazz.getConstructor(int.class, String.class);
 95         Person person = (Person) cons.newInstance(20, "兮兮");
 96         System.out.println(person);
 97     }
 98     
 99     @Test
100     public void testGeneric() throws Exception{
101         String className = "com.aop.Person";
102         Class<?> clazz = Class.forName(className);
103         
104         //1、获取父类,只能得到父类的名称
105         Class<?> superClazz = clazz.getSuperclass();
106         System.out.println(superClazz);
107         
108         //2、获取带泛型的父类
109         Type type = clazz.getGenericSuperclass();
110         System.out.println(type);
111         
112         //3、获取父类的泛型类(重要)
113         ParameterizedType param = (ParameterizedType)type;
114         Type[] argmts = param.getActualTypeArguments();
115         Class<?> claz = (Class<?>)argmts[0];
116         System.out.println(claz);
117     }
118 
119 }
public class TestReflection

 

 

参考:尚硅谷java视频

 

5、java反射基础

标签:

原文地址:http://www.cnblogs.com/lj95801/p/5392628.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!