浅谈Java反射机制 之 获取类的 方法 和 属性(包括构造函数)
上一篇 获取 类 的字节码文件 我们讲到了获取类的字节码文件的三种方法
第三种方法通过getClass("全路径名")获取字节码文件最符合要求
1、获取构造方法
先贴上我们要获取的类结构
import java.util.Date; public class Student { private String name; private Integer age; private Date Birthday; public Student(){ } private Student(String name){ this.name=name; } private Student(Integer age){ this.age=age; } private Student(Date Birthday){ this.Birthday=Birthday; } public Student(String name,Integer age){ this.name=name; this.age=age; } public Student(Integer age,String name){ this.name=name; this.age=age; } public Student(String name,Date Birthday){ this.name=name; this.Birthday=Birthday; } public Student(Date Birthday,String name){ this.name=name; this.Birthday=Birthday; } public Student(Integer age,Date Birthday){ this.age=age; this.Birthday=Birthday; } public Student(Date Birthday,Integer age){ this.age=age; this.Birthday=Birthday; } public Student(String name,Integer age,Date Birthday){ this.age=age; this.name=name; this.Birthday=Birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return Birthday; } public void setSex(Date sex) { this.Birthday = Birthday; } }
通过 getConstructors() getDeclaredConstructors() getConstructor() getDeclaredConstructor()这四个方法获取各种构造方法
import java.lang.reflect.Constructor; import java.util.Date; public class Test04 { public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException{ //加载Class对象 //会报出不存在该类的异常 Class c=Class.forName("com.reflection.model.Student"); //获取所有公用构造方法 System.out.println("================获取所有公共的构造方法================="); Constructor[] constructors=c.getConstructors(); for (Constructor constructor:constructors) { System.out.println("公共的构造方法:"+constructor); } //获取所有构造方法 System.out.println("================获取所有的构造方法================="); Constructor[] declaredconstructors=c.getDeclaredConstructors(); for (Constructor constructor:declaredconstructors) { System.out.println("所有构造方法:"+constructor); } //获取公有&无参构造方法 System.out.println("================获取公有&无参构造方法================="); //会报出没有该方法的异常 Constructor constructor1=c.getConstructor(null); System.out.println("公有&无参构造方法:"+constructor1); //获取公有&有参构造方法 System.out.println("================获取公有&有参构造方法================="); //会报出没有该方法的异常 Constructor constructor2=c.getConstructor(new Class[]{String.class,Integer.class, Date.class}); System.out.println("公有&有参构造方法:"+constructor2); Constructor constructor3=c.getConstructor(new Class[]{String.class,Integer.class}); System.out.println("公有&有参构造方法:"+constructor3); //获取私有&有参构造方法 System.out.println("================获取私有&有参构造方法================="); //会报出没有该方法的异常 Constructor declaredconstructor1=c.getDeclaredConstructor(new Class[]{String.class}); System.out.println("私有&有参构造方法:"+declaredconstructor1); } }
结果:
================获取所有公共的构造方法=================
公共的构造方法:public com.reflection.model.Student(java.lang.Integer,java.lang.String)
公共的构造方法:public com.reflection.model.Student(java.lang.String,java.util.Date)
公共的构造方法:public com.reflection.model.Student(java.util.Date,java.lang.String)
公共的构造方法:public com.reflection.model.Student(java.lang.Integer,java.util.Date)
公共的构造方法:public com.reflection.model.Student(java.util.Date,java.lang.Integer)
公共的构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer,java.util.Date)
公共的构造方法:public com.reflection.model.Student()
公共的构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer)
================获取所有的构造方法=================
所有构造方法:public com.reflection.model.Student(java.lang.Integer,java.lang.String)
所有构造方法:public com.reflection.model.Student(java.lang.String,java.util.Date)
所有构造方法:public com.reflection.model.Student(java.util.Date,java.lang.String)
所有构造方法:public com.reflection.model.Student(java.lang.Integer,java.util.Date)
所有构造方法:public com.reflection.model.Student(java.util.Date,java.lang.Integer)
所有构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer,java.util.Date)
所有构造方法:public com.reflection.model.Student()
所有构造方法:private com.reflection.model.Student(java.lang.String)
所有构造方法:private com.reflection.model.Student(java.lang.Integer)
所有构造方法:private com.reflection.model.Student(java.util.Date)
所有构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer)
================获取公有&无参构造方法=================
公有&无参构造方法:public com.reflection.model.Student()
================获取公有&有参构造方法=================
公有&有参构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer,java.util.Date)
公有&有参构造方法:public com.reflection.model.Student(java.lang.String,java.lang.Integer)
================获取私有&有参构造方法=================
私有&有参构造方法:private com.reflection.model.Student(java.lang.String)
结论:
getConstructors()返回所有
public
的构造器。
getDeclaredConstructors()返回所有
private
和public
构造器。
getConstructor()
返回指定参数类型public
的构造器。
getDeclaredConstructor()
返回指定参数类型的private
和public
构造器。
2、获取类属性
将 1 中的 Student 类中的 name 字段设为 public
public String name;
通过 getFields() getDeclaredFields() getField() getDeclaredField()这四个方法获取各种字段
import java.lang.reflect.Field; public class Test05 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { //加载Class对象 //会报出不存在该类的异常 Class c=Class.forName("com.reflection.model.Student"); //获取所有公用公共字段 System.out.println("================获取所有公共字段================="); Field[] fields=c.getFields(); for (Field field:fields) { System.out.println("公共字段:"+field); } //获取所有字段 System.out.println("================获取所有的字段(公共的、私有的)================="); Field[] declaredFields=c.getDeclaredFields(); for (Field declaredfield:declaredFields) { System.out.println("所有字段:"+declaredfield); } System.out.println("================根据字段名获取公共字段================="); //根据字段名获取公共字段 Field field1=c.getField("name"); System.out.println("根据字段名获取公共字段:"+field1); System.out.println("================根据字段名私有字段================="); //根据字段名获取公共字段 Field field2=c.getDeclaredField("age"); System.out.println("根据字段名获取公共字段:"+field2); } }
结果:
================获取所有公共字段=================
公共字段:public java.lang.String com.reflection.model.Student.name
================获取所有的字段(公共的、私有的)=================
所有字段:public java.lang.String com.reflection.model.Student.name
所有字段:private java.lang.Integer com.reflection.model.Student.age
所有字段:private java.util.Date com.reflection.model.Student.Birthday
================根据字段名获取公共字段=================
根据字段名获取公共字段:public java.lang.String com.reflection.model.Student.name
================根据字段名私有字段=================
根据字段名获取公共字段:private java.lang.Integer com.reflection.model.Student.age
结论:
getFields()返回所有
public
的字段。
getDeclaredFields()返回所有
private
和public字段
。
getField()
返回指定字段名public
的字段。
getDeclaredField()
返回指定字段名的private
和public字段名
。
3、获取类中的方法
在 1 中的Student类中定义几个方法
public void method1(String str){ System.out.println("public 修饰的方法"); } private void method2(){ System.out.println("private 修饰的方法"); } String method3(String name,Integer sex,Date age){ System.out.println("默认修饰"+name+" "+sex+" "+age); return name+" "+sex+" "+age; } protected void method4(){ System.out.println("protected 修饰的方法"); }
通过 getMethods() getDeclaredMethods() getMethod() getDeclaredMethod()这四个方法获取各种方法
import java.lang.reflect.Method; import java.util.Date; public class Test06 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { //加载Class对象 //会报出不存在该类的异常 Class c=Class.forName("com.reflection.model.Student"); //获取所有公共方法 System.out.println("================获取所有公共方法================="); Method[] methods=c.getMethods(); for (Method method:methods) { System.out.println("公共方法:"+method); } //获取所有方法 System.out.println("================获取所有的方法================="); Method[] declaredMethods=c.getDeclaredMethods(); for (Method declaredmethod:declaredMethods) { System.out.println("所有方法:"+declaredmethod); } System.out.println("================获取特定(带参)方法================="); Method method1=c.getMethod("method1",String.class); System.out.println("特定(带参)方法:"+method1); System.out.println("================获取特定(不带参)方法================="); Method method2=c.getDeclaredMethod("method2"); System.out.println("特定(不带参)方法:"+method2); System.out.println("================获取特定(多参)方法================="); Method method3=c.getDeclaredMethod("method3", String.class, Integer.class, Date.class); System.out.println("特定(多参)方法:"+method3); } }
结果:
================获取所有公共方法=================
公共方法:public java.lang.String com.reflection.model.Student.getName()
公共方法:public void com.reflection.model.Student.setName(java.lang.String)
公共方法:public void com.reflection.model.Student.method1(java.lang.String)
公共方法:public void com.reflection.model.Student.setSex(java.util.Date)
公共方法:public java.util.Date com.reflection.model.Student.getBirthday()
公共方法:public java.lang.Integer com.reflection.model.Student.getAge()
公共方法:public void com.reflection.model.Student.setAge(java.lang.Integer)
公共方法:public final void java.lang.Object.wait() throws java.lang.InterruptedException
公共方法:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
公共方法:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
公共方法:public boolean java.lang.Object.equals(java.lang.Object)
公共方法:public java.lang.String java.lang.Object.toString()
公共方法:public native int java.lang.Object.hashCode()
公共方法:public final native java.lang.Class java.lang.Object.getClass()
公共方法:public final native void java.lang.Object.notify()
公共方法:public final native void java.lang.Object.notifyAll()
================获取所有的方法=================
所有方法:public java.lang.String com.reflection.model.Student.getName()
所有方法:public void com.reflection.model.Student.setName(java.lang.String)
所有方法:private void com.reflection.model.Student.method2()
所有方法:public void com.reflection.model.Student.method1(java.lang.String)
所有方法:java.lang.String com.reflection.model.Student.method3(java.lang.String,java.lang.Integer,java.util.Date)
所有方法:public void com.reflection.model.Student.setSex(java.util.Date)
所有方法:public java.util.Date com.reflection.model.Student.getBirthday()
所有方法:protected void com.reflection.model.Student.method4()
所有方法:public java.lang.Integer com.reflection.model.Student.getAge()
所有方法:public void com.reflection.model.Student.setAge(java.lang.Integer)
================获取特定(带参)方法=================
特定(带参)方法:public void com.reflection.model.Student.method1(java.lang.String)
================获取特定(不带参)方法=================
特定(不带参)方法:private void com.reflection.model.Student.method2()
================获取特定(多参)方法=================
特定(多参)方法:java.lang.String com.reflection.model.Student.method3(java.lang.String,java.lang.Integer,java.util.Date)
结论:
getMethods()返回所有
public
的方法,通过结果可以看出getMethods()连父类中的
。public
方法也可以获取到
getDeclared
Method
s()返回所有private
和public方法名,
。getDeclared
Method
s()获取不到父类中的方法,只能获取到本来中的方法
get
返回指定字段名Method
()public
的方法名。
getDeclared
返回指定字方法名的Method
()private
和public字段名
。
注:
由getMethods()和
getDeclared
Method
s()方法我们推测获取字段的方法和获取构造函数的方法
应该和getMethods()和
getDeclared
Method
s()一样,
为了验证
,又定义了一个People类,getFields()和
getDeclaredFields()
public class People { public String head; public String foot; }
Student继承People
================获取所有公共字段=================
公共字段:public java.lang.String com.reflection.model.Student.name
公共字段:public java.lang.String com.reflection.model.People.head
公共字段:public java.lang.String com.reflection.model.People.foot
================获取所有的字段(公共的、私有的)=================
所有字段:public java.lang.String com.reflection.model.Student.name
所有字段:private java.lang.Integer com.reflection.model.Student.age
所有字段:private java.util.Date com.reflection.model.Student.Birthday
getFields()
可以获取到父类的所有公共的字段,
getDeclaredFields()只能获取到本类中的字段
================获取所有公共的构造方法=================
公共的构造方法:public com.reflection.model.Student(java.lang.String,java.lang.String)
================获取所有的构造方法=================
所有构造方法:public com.reflection.model.Student(java.lang.String,java.lang.String)
上面的结果也证明了
获取到父类的构造方法,getConstructors()不能
getDeclaredConstructors()也
只能获取到本类中的
构造方法