JAVA反射机制详解

来源:互联网 发布:淘宝手串哪家好 编辑:程序博客网 时间:2024/06/10 09:41

3.4 . 通过Class类取得完整结构(了解)

通过Class类中的很多方法,可以轻易得取得一个类中定义的全部构造方法,普通方法,常量,变量等等.例如: 现在假设有如下的类: 

package org.lxh.demo.classdemo04;

interface Info{

public static final String AUTHOR = "MICHELE";

public String getInfo();

public String say(String name,String content);

public void sayHello();

}

public class Person implements Info{

private String name;

private int age;

public Person(){

}

public String getInfo() {

return "getInfo is hello world !";

}

public String say(String name, String content) {

return name + "说了:" + content;

}

public void sayHello() {

System.out.println("hello --> " + AUTHOR);

}

public Person(String name ){

this.setName(name);

}

public Person(String name , int age){

this(name);

this.setAge(age);

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String toString() {

return "姓名:" + this.name + "; 年龄:" + this.age;

}

}

下面通过一系列的反射, 完成操作.

 

3.4.1 . 取得继承的父类

在Class类中存在以下的方法, 可以取得一个继承的父类:

public Class<? super T> getSuperclass()

 

范例: 取得父类.

package org.lxh.demo.classdemo04;

public class GetSuperClassDemo {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Class<?> sc = c.getSuperclass(); 

System.out.println(sc.getName());

}

}

此时Person类没有继承任何父类,所以其父类就是Object类.

 

3.4.2 . 取得实现的全部接口

一个类中可以实现多个接口,所以在Class类中提供了以下方法:

public Class<?>[] getInterfaces()

接口本身就是一个特殊的类, 所以会以Class的对象数组形式返回. 

package org.lxh.demo.classdemo04;

public class GetInterfacesDemo {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Class<?> inter[] = c.getInterfaces();//得到全部接口

for(int i = 0 ; i < inter.length ; i++){

System.out.println(inter[i].getName());//输出全部接口内容

}

}

}

 

3.4.3 . 取得一个类的全部构造方法

之前已经演示过如何取得一个类的构造方法 

public Constructor<?>[]  getConstructors() throws SecurityException

 

在Person类中定义了三个构造方法,那么此时可以全 部取出

package org.lxh.demo.classdemo04;

import java.lang.reflect.Constructor;

public class GetConstructorDemo01 {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Constructor<?> con[] = c.getConstructors();//得到全部构造

for(int i = 0 ; i < con.length ; i++){

System.out.println(con[i]);//输出全部构造内容

}

}

}

以上确实得到了全部的构造方法,但是程序有一个弊病,是通过toString()自动输出的.如果现在直接通过getName()方法取得,则只能取得构造方法的名字,而访问的修饰符和参数完全不见,所以,如果现在想手工拼凑出一个完整的构造方法,还需要以下的几个方法支持:

得到访问修饰符: public int getModifiers()

得到全部的参数: public Class<?> getParameterTypes()

package org.lxh.demo.classdemo04;

import java.lang.reflect.Constructor;

public class GetConstructorDemo01 {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Constructor<?> con[] = c.getConstructors();//得到全部构造

for(int i = 0 ; i < con.length ; i++){

int mod = con[i].getModifiers();//得到修饰符

Class<?> param[] = con[i].getParameterTypes();

System.out.print(mod + " ");

System.out.print(con[i].getName() + " (");//输出全部构造内容

for(int x = 0 ; x < param.length ; x++){

System.out.print(param[x].getName() + "arg-" + x);

if(x == param.length - 1)

{

System.out.print(",");

}

}

System.out.println(")");

}

}

}

此时的程序输出如下:

1 org.lxh.demo.classdemo04.Person (java.lang.Stringarg-0intarg-1,)

1 org.lxh.demo.classdemo04.Person (java.lang.Stringarg-0,)

1 org.lxh.demo.classdemo04.Person ()

从结果中可以发现, 访问修饰符是数字, 并还是之前的public, 在实际的开发中所有的访问权限

基本上都是以数字的形式表示出来的,这样程序会比较好写,对于public,private而言, 本身也是对应

的一个数字. 而且对于public static final,实际上是属于三个值相加的结果, 所以,如果要想正确地还原一个方法的访问修饰符,则必须使用一个Modifer(java.lang.reflect)的类进行还原.  

Public static string toString(int mod)

通过以上的方式可以还原修饰符:

package org.lxh.demo.classdemo04;

import java.lang.reflect.Constructor;

import java.lang.reflect.Modifier;

public class GetConstructorDemo03 {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Constructor<?> con[] = c.getConstructors();//得到全部构造

for(int i = 0 ; i < con.length ; i++){

int mod = con[i].getModifiers();//得到修饰符

String str = Modifier.toString(mod);//还原权限

Class<?> param[] = con[i].getParameterTypes();

System.out.print(str + " ");//访问修饰符(单词表示)

System.out.print(con[i].getName() + " (");//输出全部构造内容

for(int x = 0 ; x < param.length ; x++){

System.out.print(param[x].getName() + "arg-" + x);

if(x == param.length - 1)

{

System.out.print(",");

}

}

System.out.println(")");

}

}

Myeclipse 的智能提示也是运用以上的方法拼凑出来的

 

 

3.4.4 . 取得一个类的全部方法

在Class 类中定义了以下的方法,通过此方法可以取得一个类中的全部方法:

public Method[] getMethods() throws SecurityException

范例: 得到Person类的全部方法

package org.lxh.demo.classdemo04;

import java.lang.reflect.Method;

public class GetMethodDemo {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Method m[] = c.getMethods(); //得到全部的方法

for(int i = 0 ; i < m.length ; i++){

System.out.println(m[i]);//输出全部构造内容

}

}

以上是取得一个类中全部方法的操作, 是目前最方便的.

但是与构造方法一样, 也可以通过反射机制慢慢取得.此时需要以下方法的支持:

?取得方法的返回值类型: public Class<?> getReturnType()

?取得方法的全部参数:public Class<?>[] getParameterTypes()

?取得方法的抛出异常: public Class<?>[] getExceptionTypes()

package org.lxh.demo.classdemo04;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

public class GetMethodDemo2 {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

Method m[] = c.getMethods(); //得到全部的方法

for(int i = 0 ; i < m.length ; i++){

String mod = Modifier.toString(m[i].getModifiers());//取得访问权限

String metName = m[i].getName();//方法名称

Class<?> ret = m[i].getReturnType();//返回值类型

Class<?> param[] = m[i].getParameterTypes();//全部的参数类型

Class<?> exc[] = m[i].getExceptionTypes();//全部异常

System.out.print(mod + " ");

System.out.print(ret + " ");

System.out.print(metName + " (");

for(int x = 0 ; x < param.length ;x++){

System.out.print(param[x] + "arg-" + x);

if(x < param.length - 1){

System.out.print(",");

}

}

System.out.print(")");

if(exc.length > 0){

System.out.print("throws ");

for(int x = 0 ; x < exc.length ;x++){

System.out.print(exc[x].getName());

if(x < exc.length - 1){

System.out.print(",");

}

}

}

System.out.println();

}

}

 

3.4.5 . 取得一个类的全部属性

Class 类中定义的可以取得一类中全部属性的方法:

 

?得到继承而来的公共属性:public Field[] getFields() throws SecurityException

?得到自定义的属性: public Field[] GetDeclaredFields() throws SecurityException

package org.lxh.demo.classdemo04;

import java.lang.reflect.Modifier;

import java.lang.reflect.Field;

public class GetFieldsDemo01 {

public static void main(String[] args) throws Exception{

Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");

{

Field f[] = c.getFields();//得到全部变量

for(int i = 0 ; i < f.length ; i++){

String mod = Modifier.toString(f[i].getModifiers());

System.out.print(mod + " ");

System.out.print(f[i].getType().getName());

}

}

System.out.println();

{

Field f[] = c.getDeclaredFields();//得到全部变量

for(int i = 0 ; i < f.length ; i++){

String mod = Modifier.toString(f[i].getModifiers());

System.out.print(mod + " ");

System.out.println(f[i].getType().getName());

}

}

}

}


原创粉丝点击