Java 中所有的对象都是primitive 类型或者 reference类型。所有的reference类型都继承自Object类。对于任何继承自Object类的对象,jvm提供了一个Class类的实例,使得可以对运行时对象获取其类型信息。如下图所示:
本文以一个继承自Fruit的Apple为例进行介绍,所有的示例部分都在最后的代码中。
Class 类 ,java.lang.Class
声明一个Class 对象,和普通类声明对象时一样,类名 + 对象名,即Class classObj = null
获取Class 对象有三种方法,请注意它们的区别
Object.getClass()
.class
Class.forName(StringclassName)
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