Java 中所有的对象都是primitive 类型或者 reference类型。所有的reference类型都继承自Object类。对于任何继承自Object类的对象,jvm提供了一个Class类的实例,使得可以对运行时对象获取其类型信息。如下图所示:
本文以一个继承自Fruit的Apple为例进行介绍,所有的示例部分都在最后的代码中。
Class 类 ,java.lang.Class
一 获取Class对象
声明一个Class 对象,和普通类声明对象时一样,类名 + 对象名,即Class classObj = null
获取Class 对象有三种方法,请注意它们的区别
Object.getClass()
.class
Class.forName(StringclassName)
二 获取Class的成员
Class中的成员包括三类:fileds,methods,constructors
对Class的这三种成员访问有两种方式:一种是获取所有的成员;一种是按需获取,如获取名字叫做getName的方法。
不同的方法对Class成员的访问权限也不尽相同,详细的Class成员访问机制如图所示:
fields
getDeclaredMethods()
就可以获取所有类本身的方法,不能获取继承而来的field,可以获取private field。
而getMethods()
可以获取本身的方法和从父类继承来的方法,不能获取private field。
getDeclaredField(Stringname),可以通过field的名字获取对应的field,如果没有该域,则抛出异常。
Construtor
Class对象Class.getConstructor(Class[]parameterTypes)可以按照期望的Construtor参数列表,获取类的Construtor,这里以获取Apple类的Apple(String address)这个Construtor为例介绍。
三 利用Class创建实例,
有两种方法利用反射进行创造实例
<1>Class.newInstance()
<2>Constructor.newInstance() (推荐)
区别:
方法<1>只能调用无参Constructor,
方法<1>可能抛出任何异常,方法<2>利用InvocationTargetException
进行封装
方法<1>需要Constructor是visible,方法<2> Constructor可以是private,方法<2>中按照前面获取的Construtor,并且指定需要的参数。
代码如下:
Fruit类
public class Fruit{
public String name;
private int sweet; //甜度
private int sour; //酸度
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSweet() {
return sweet;
}
public void setSweet(int sweet) {
this.sweet = sweet;
}
public int getSour() {
return sour;
}
public void setSour(int sour) {
this.sour = sour;
}
}
Apple类
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Apple extends Fruit {
public String address;
private int days;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public Apple(){
}
public Apple(String address){
this.address = address;
}
public static void main(String []args){
Class classObj = null;
Apple apple = new Apple();
try {
//-------------- 获取Class对象 -------------------
// Class.forName
classObj = Class.forName("java.lang.Integer");
System.out.println("Class.forName is "+classObj);
// Object.getClass()
classObj = apple.getClass();
System.out.println(".getClass is "+classObj);
// .class
classObj = Apple.class;
System.out.println(".class is "+classObj);
// ---------------- 获取Class的field ----------------
// 获取该Class的所有declared fileds
Field [] declaredFields = classObj.getDeclaredFields();
System.out.println("The Declared fields of Apple is :");
for (Field field : declaredFields){
System.out.print(field.getName() +" ");
}
System.out.println();
// 获取该Class的所有fields,包括继承得来的field
Field [] fields = classObj.getFields();
System.out.println("All fields of Apple is :");
for (Field field : fields){
System.out.print(field.getName() +" ");
}
// 按照field的名字获取field
Field singleField = classObj.getDeclaredField("days");
System.out.println("field with name days is : "+ singleField.getName());
// ---------------- 两种实例化方法 -------------------
// 利用Class.newIntance()
Object appleObj = classObj.newInstance();
System.out.println(appleObj instanceof Apple);
// 利用Construtor.newInstance()
Class []parameterTypes = {Class.forName("java.lang.String")};
Constructor constructor = classObj.getConstructor(parameterTypes);
appleObj = constructor.newInstance("beijing");
if(appleObj instanceof Apple){
apple = (Apple) appleObj;
System.out.println("Apple address is " +apple.getAddress());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
Class.forName is class java.lang.Integer
.getClass is class Apple
.class is class Apple
The Declared fields of Apple is :
address days
All fields of Apple is :
address name field with name days is : days
true
Apple address is beijing