首页 > 代码库 > 反射(基础知识)

反射(基础知识)

一、反射的概念

反射是java语言提供的一项非常吸引人的特性,利用反射可以在运行时对程序进行动态的控制。开发使用反射特性的程序需要使用一套专门的工具类,这些类大部分都位于java.lang.reflect包中。

二、Class类

Class类属于java.lang包,不需要使用import语句引入特殊的包就可以使用,其对象代表一个类,携带类的相应信息,主要包括构造器、方法、成员变量等。其实,java程序运行过程中,每个类被加载都在内存中产生一个对应的Class类对象,在普通应用程序中这些对象是由系统自动维护的,开发人员不需要关心。

1、对类和对象的理解

(1)在面向对象的世界里,万事万物皆对象

(2)java语言中静态的成员、普通数据类型类不是对象。

(3)类是对象,类是java.lang.Class类的实例对象。(任何一个类都是Class的实例对象)

2、任何类都是Class的实例对象,这个实例对象有三种表示方式(可以通过三种方式获取Class类对象

类类型不可以使用Class类的构造器来创建Class类对象,只能使用其提供的静态工厂方法来获取对象。

(1)实际上,在告诉我们任何类都有一个隐含的静态成员变量Class,所以可以通过下面方式获取Class类对象 

Class c1=FOO.class;                         //   FOO是一个类

 

(2)已知一个类的实例对象,通过getClass方法获取Class类对象

 1 FOO foo=new FOO();

2  Class c1=foo.getClass(); 

注:c1,c2都代表了FOO类的Class类对象,但是一个类只可能是Class类的一个实例对象。

 1 package Reflect;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         FOO foo=new FOO();
 7         Class c=foo.getClass();
 8         Class c1=FOO.class;
 9         System.out.println(c1==c);
10     }
11 }

运行结果:

true

(3)通过Class.forName(String className),className指出类的全称名。,如果找不到,就会抛出ClassNotFoundException异常

1     try {
2             Class c3=Class.forName("Reflect.FOO");
3         } catch (ClassNotFoundException e) {
4             // TODO Auto-generated catch block
5             e.printStackTrace();
6         }
7     }

3、Class类的常用方法

Class类没有构造方法,所以很自然创建Class类对象,不能通过构造器来创建,而只能通过其提供的静态工厂方法来获取对象。Filed、Method、Constructor为java.lang.reflect包的类,它们分别代表了成员变量、方法、构造器,分别携带对应成员变量、方法、构造器信息。package类在java.lang包中,其对象代表一个包,携带相应包的信息。

Class类的常用方法表

方法关键字

含义

public Method[] getDeclaredMethods()

获取声明的所有的方法

public Method getDeclaredMethod("方法名",参数类型.class,……)

获得特定的方法

public Constructor[] getDeclaredConstructors()

获取所有声明的构造方法

public Constructor[] getConstructors()

获取所有的构造方法

public Constructor getDeclaredConstructor(参数类型.class,……)

获取特定的构造方法
public Field[] getFields()

获取所有成员变量

public  Field[] getDeclaredFields()

获取所有声明的成员变量

public  Field getField(String name)

获取指定的成员变量

 public Package getPackage()

返回Class对象所对应类所在的包 

public String getName()

返回Class对象对应类的名称

public static Class forName(String className)

通过此方法获取指定名称的类对应的Class对象,className指出类的全名称

Public Object newInstance()

调用默认的无参构造器新建Class对象对应类的一个对象。

注:标红的两个方法是Class类实现动态加载类的核心方法。

通过newInstance()方法创建的对象与普通方式创建的对象在使用上完全相同(区别:用于动态加载类后的实例化)。

代码示例:

 1 package Reflect;
 2 
 3 public interface OfficeAble {
 4 
 5     public void start();
 6 }
 7 
 8 
 9 package Reflect;
10 
11 public class Word implements OfficeAble {
12 
13     private String name;
14     private String gender;
15     public Word() {
16         System.out.println("word的构造方法1~~");
17     }
18     
19     public Word(String name,String gender) {
20         this.name=name;
21         this.gender=gender;
22         System.out.println("word的构造方法1~~"+name+" "+gender);
23     }
24     
25     @Override
26     public void start() {
27         System.out.println("word..start.......");
28     }
29     
30     public void start1() {
31         System.out.println("word..start1.......");
32     }
33 
34 }
35 
36 package Reflect;
37 
38 import java.lang.reflect.Constructor;
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Method;
41 
42 public class OfficeBetter {
43 
44     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
45         //动态加载类,在运行时刻加载
46         Class c=Class.forName("Reflect.Word");
47         //通过类类型,创建该类对象
48         OfficeAble oa=(OfficeAble) c.newInstance();
49         oa.start();
50         
51         //获取Word类中所有构造函数对象,所有成员变量对象,所有方法对象
52         Constructor []cs=c.getConstructors();
53         Field []fd=c.getFields();
54         Method []md=c.getMethods();
55         
56         //遍历构造函数对象,成员变量对象,方法对象,打印他们的信息
57         for (Method method : md) {
58             System.out.println(method.getName()+" "+method.getParameterCount());
59         }
60 
61         for (Field field : fd) {
62             System.out.print(field.getName()+" ");
63         }
64         System.out.println();
65         
66         for (Constructor constructor : cs) {
67             System.out.println(constructor.getName()+" "+constructor.getParameterCount());
68         }
69     }
70 
71 }

运行结果:

 1 word的构造方法1~~
 2 word..start.......
 3 start 0
 4 start1 0
 5 wait 0
 6 wait 2
 7 wait 1
 8 equals 1
 9 toString 0
10 hashCode 0
11 getClass 0
12 notify 0
13 notifyAll 0
14 
15 Reflect.Word 0
16 Reflect.Word 2

 

反射(基础知识)