反射应用--取得类的结构

1,目标:

通过反射取得类的全部接口,

取得类所继承的父类

取得类全部构造方法

通过反射取得类的全部方法

通过反射取得一个类的全部属性。

具体类型

反射的深入-取得类的结构

要想通过反射取得类的结构,需要使用接口:java.lang.reflect包中的以下类:

1,Constructor:表示类的构造方法

2,Field:表示类中属性。

3,Method:表示类中的方法。

这三个类都是AccessibleObject的子类。

实践:

一,设置一个类:

package 类集;

interface China{    // 定义China接口
    public static final String NATIONAL = "China" ;    // 定义全局常量
    public static final String AUTHOR = "小华" ;    // 定义全局常量
    public void sayChina() ;        // 无参的,没有返回值的方法
    public String sayHello(String name,int age) ;    // 定义有两个参数的方法,并返回内容
}
public class Person implements China{
    private String name ;
    private int age ;
    public Person(){    // 无参构造
    }
    public Person(String name){
        this.name = name ;    // 设置name属性
    }
    public Person(String name,int age){
        this(name) ;
        this.age = age ;
    }
    public void sayChina(){    // 覆写方法
        System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;
    }
    public String sayHello(String name,int age){
        return name + ",你好!我今年:" + age + "岁了!" ;
    }
    public void setName(String name){
        this.name = name ;
    }
    public void setAge(int age){
        this.age = age ;
    }
    public String getName(){
        return this.name ;
    }
    public int getAge(){
        return this.age ;
    }
};

1,取得类实现的接口:

要想取得全部接口:可以使用Class类中的方法:

 Class<?>[] getInterfaces()
          确定此对象所表示的类或接口实现的接口 

因为一个类可以同时取得多个接口,所以此处将以一个数组的形式返回实现的全部接口。

package 类集;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){            //处理异常
            e.printStackTrace() ;
        }
        Class<?> c[] = c1.getInterfaces() ;    // 以数组形式返回实现的全部接口
        for(int i=0;i<c.length;i++){
            System.out.println("实现的接口名称:" + c[i].getName()) ;    // 输出接口名称
        }
    }
}

输出结果:

类集.China

总结:

要想取得一个类所实现的全部接口,必须使用Class类中getInterface()方法,

定义如下:public Class<?> [] getInterface();

此方法返回一个Class类的对象数组,之后就可以利用Class类中的getName()输出即可。

取得类所继承的父类

要想取得父类,使用Class类中的getSupperClass()方法,

定义如下:

 Class<? super T> getSuperclass()
          返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 

此方法返回的是class实例 ,  和接口一样,通过getName()方法获得。

一个类继承一个父类,如果没有指明继承哪个类,则肯定继承的是object类

取得父类。

package 类集;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1=null;
        try {
            c1=Class.forName("类集.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Class<?> c2 = c1.getSuperclass() ;    // 取得父类
        System.out.println("父类名称:" + c2.getName()) ;
    }
}

输出结果:

父类名称:java.lang.Object

取得公共构造方法

 Constructor<T> getConstructor(Class<?>... parameterTypes)
          返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 

返回一个对象。注意要处理异常。

实例:

package 类集;
import java.lang.reflect.Constructor;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Constructor<?> con=null;
        try {
             con = c1.getConstructor();
        } catch (NoSuchMethodException | SecurityException e) {
            e.printStackTrace();
        }

        System.out.println("构造方法:" + con) ;     // 输出构造,直接打印
    }
}

输出结果:

构造方法:public 类集.Person()

取得全部构造方法:

通过方法:getConstructors()。

 Constructor<?>[] getConstructors()
          返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 

实例:

package 类集;
import java.lang.reflect.Constructor;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Constructor<?> con[] = c1.getConstructors() ;    // 取得一个类中的全部构造
        for(int i=0;i<con.length;i++){
            System.out.println("构造方法:" + con[i]) ;     // 输出构造,直接打印
        }
    }
}

输出结果:

构造方法:public 类集.Person(java.lang.String,int)
构造方法:public 类集.Person(java.lang.String)
构造方法:public 类集.Person()

以上操作确实取得了类中的构造方法,但是此时是通过对象直接打印取得的,输出的时候定会自动调用constructor里面的toString()方法

如果不想用自带的toString()怎么办?

constructor类中存在以下方法,

1)取得修饰符。getModifiers() 

 int getModifiers()
          以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。 

2)取得方法名称:getName();

 String getName()
          以字符串形式返回此构造方法的名称。 

3)取得参数的类型。getParameterTypes

 Class<?>[] getParameterTypes()
          按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。 

实例:

package 类集;
import java.lang.reflect.Constructor;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Constructor<?> con[] = c1.getConstructors() ;    // 取得一个类中的全部构造
        for(int i=0;i<con.length;i++){
            Class<?> p[] = con[i].getParameterTypes() ;        // 得到某个构造方法中的全部参数
            System.out.print("构造方法:" ) ;     // 输出构造,直接打印
            System.out.print(con[i].getModifiers() + " ") ;    // 得到修饰符
            System.out.print(con[i].getName()) ;    // 取得构造方法的名字
            System.out.print("(") ;
            for(int j=0;j<p.length;j++){          //遍历参数,输出
                System.out.print(p[j].getName() + " arg" + i) ;
                if(j<p.length-1){
                    // 判断此是否是最后一个参数
                    System.out.print(",");    // 输出“,”
                }
            }
            System.out.println("){}") ;
        }
    }
}

输出结果:

构造方法:1 类集.Person(java.lang.String arg0,int arg0){}
构造方法:1 类集.Person(java.lang.String arg1){}
构造方法:1 类集.Person(){}

从之前程序可以发现,取得权限的时候,返回的是一个数字,而不是public,这是因为在java中对于修饰符是使用数字表示出来的, 所以需要还原修饰符出来。

则必须依靠Modifier类完成,定义在reflect包中,直接使用Modify类的以下方法即可将修饰符操作。

static String toString(int mod)
          返回描述指定修饰符中的访问修饰符标志的字符串。 

利用以上方法还原修饰符。

package 类集;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Constructor<?> con[] = c1.getConstructors() ;    // 取得一个类中的全部构造
        for(int i=0;i<con.length;i++){
            Class<?> p[] = con[i].getParameterTypes() ;        // 得到构造方法中的全部参数
            System.out.print("构造方法:" ) ;     // 输出构造,直接打印
            int mo = con[i].getModifiers() ; // 得到所要的访问权限
            System.out.print(Modifier.toString(mo) + " ") ;    // 得到修饰符
            System.out.print(con[i].getName()) ;    // 取得构造方法的名字
            System.out.print("(") ;
            for(int j=0;j<p.length;j++){
                System.out.print(p[j].getName() + " arg" + i) ;
                if(j<p.length-1){
                    // 判断此是否是最后一个参数
                    System.out.print(",");    // 输出“,”
                }
            }
            System.out.println("){}") ;
        }
    }
}

输出结果:

构造方法:public 类集.Person(java.lang.String arg0,int arg0){}
构造方法:public 类集.Person(java.lang.String arg1){}
构造方法:public 类集.Person(){}

取得全部方法

可以使用Class类中的getDeclaredMethods,此方法返回一个method类对象数组,如果想要进一步取得方法具体信息,必须依靠Method类。

 Method[] getDeclaredMethods()
          返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 

method类有以下方法:

getReturnType() ; // 取得全部的返回值

getParameterTypes() ; // 取得全部参数

getModifiers():取得修饰符

getName() 获取名称

getExceptionTypes() ; // 取出异常

实例:

package 类集;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Method m[] = c1.getMethods() ;    // 取得全部方法
        for(int i=0;i<m.length;i++){
            Class<?> r = m[i].getReturnType() ;    // 得到返回值类型
            Class<?> p[] = m[i].getParameterTypes() ;    // 取得全部参数的类型
            int xx = m[i].getModifiers() ;    // 类得到修饰符
            System.out.print(Modifier.toString(xx) + " ") ;    //利用Modifier类,输出修饰符
            System.out.print(r + " ") ;
            System.out.print(m[i].getName()) ;
            System.out.print("(") ;
            for(int j=0;j<p.length;j++){
                System.out.print(p[j].getName() + " " + "arg" + j) ;
                if(j<p.length-1){
                    System.out.print(",") ;
                }
            }
            Class<?> ex[] = m[i].getExceptionTypes() ;    // 取出异常
            if(ex.length>0){
                System.out.print(") throws ") ;
            }else{
                System.out.print(")") ;
            }
            for(int j=0;j<ex.length;j++){
                System.out.print(ex[j].getName()) ;
                if(j<p.length-1){
                    System.out.print(",") ;
                }
            }
            System.out.println() ;
        }
    }
}

输出结果:

public class java.lang.String getName()
public void setName(java.lang.String arg0)
public class java.lang.String sayHello(java.lang.String arg0,int arg1)
public int getAge()
public void setAge(int arg0)
public void sayChina()
public final void wait() throws java.lang.InterruptedException
public final void wait(long arg0,int arg1) throws java.lang.InterruptedException,
public final native void wait(long arg0) throws java.lang.InterruptedException
public boolean equals(java.lang.Object arg0)
public class java.lang.String toString()
public native int hashCode()
public final native class java.lang.Class getClass()
public final native void notify()
public final native void notifyAll()

实际上,一般开发工具经常看见随笔提示功能,实际上就是利用以上程序实现的。

取得全部属性

在反射操作中可以取得全部属性,但是有两种操作:

1,得到实现的接口,或父类中公共属性:

 Field[] getFields()
          返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 

2,得到本类中全部属性。

 Field[] getDeclaredFields()
          返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 

以上返回的欧式Filed的数组,每一个Fild对象表示类中一个属性。

Field包含的方法:

getType():得到属性类型。

getModifiers():得到修饰符的数字。

实例:

package 类集;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class GetInterfaceDemo {
    public static void main(String[] args) {
        Class<?> c1 = null ;        // 声明Class对象
        try{
            c1 = Class.forName("类集.Person") ;    // 实例化对象
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        {    // 本类属性
            Field f[] = c1.getDeclaredFields() ;    // 取得本类中的属性
            for(int i=0;i<f.length;i++){
                Class<?> r = f[i].getType() ;    // 得到属性类型
                int mo = f[i].getModifiers() ;    // 得到修饰符的数字
                String priv = Modifier.toString(mo) ; // 还原修饰符
                System.out.print("本类属性:") ;
                System.out.print(priv + " ") ;
                System.out.print(r.getName() + " ") ;    // 得到属性类型
                System.out.print(f[i].getName()) ;    // 输出属性名称
                System.out.println(" ;") ;
            }
        }
        {    // 公共属性
            Field f[] = c1.getFields() ;    // 取得本类中的公共属性
            for(int i=0;i<f.length;i++){
                Class<?> r = f[i].getType() ;    // 得到属性类型
                int mo = f[i].getModifiers() ;    // 得到修饰符的数字
                String priv = Modifier.toString(mo) ; // 还原修饰符
                System.out.print("公共属性:") ;
                System.out.print(priv + " ") ;
                System.out.print(r.getName() + " ") ;    // 得到属性类型
                System.out.print(f[i].getName()) ;    // 输出属性名称
                System.out.println(" ;") ;
            }

        }
    }
}

输出结果:

本类属性:private java.lang.String name ;
本类属性:private int age ;
公共属性:public static final java.lang.String NATIONAL ;
公共属性:public static final java.lang.String AUTHOR ;

总结:

1,在开发中,取得类的信息的操作代码用户不会经常开发,

2,一定要熟悉reflect包作用,反射机制。

3,取得属性,构造,方法的名称,修饰符等等,了解就可以了。要熟悉

时间: 2024-10-11 20:28:26

反射应用--取得类的结构的相关文章

Java反射机制(取得类的结构)

通过反射得到一个类中的完整的结构,就要使用java.lang.reflect包中的以下几个类: Constructor:表示类中的构造方法 Field:表示类中的属性 Method:表示类中的方法 Class类中的常用方法: 确定此对象所表示的类或接口实现的接口. public Class<?>[] getInterfaces() 取得父类 public Class<? super T> getSuperclass() 取得全部的构造方法 public Constructor<

java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包

首先自定义三个类 package reflection1; public interface MtInterface { void info(); } package reflection1; import java.io.Serializable; public class Creature<T> implements Serializable { private char gender; public double weight; private void breath() { Syste

反射,System.Type类

http://m.blog.csdn.net/blog/woddle/40623333 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时候就会产生一定的“回音”反射,然后把“回音”进行处理就可以显示出内脏的情况了(我不是医生也不是声学专家,不知说得是否准确^_^).2.地球内部结构:地球的内部结构大体可以分为三层:地壳.地幔和地核.地壳是固体,地

类和结构

类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法.类定义了类的每个对象(称为实例)可以包含什么数据和功能. 结构与类的区别是它们在内存中的存储方式.访问方式(类是存储在堆heap)上的引用类型,而结构是存储在栈(stack上的值类型)和它们的一些特征(如结构不支持继承).较小的数据类型使用结构可提高性能.但在语法上,结构与类非常相似,主要的区别是使用关键字siuct代替dass来声明结构. 类 类中的数据和函数称为类的成员.Microsoft的正式术语对数据成员

【java】java反射初探 ——“当类也照起镜子”

反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制就是: 提供一套完善而强大的API“反射“类的结构. 打个比方,反射机制就像是一面镜子,而类就像是一个在照着镜子的人. 镜子(反射机制)照出(反射)了人的全貌(类的全方位的信息,例如方法,成员变量和构造器等的相关信息) 为什么要照镜子? 因为不照镜子看不清楚自己的全貌,“镜子”就是为了解决这个问题出现的(为我们提供全面分析类的能力) 好吧

Java反射初探 ——“当类也学会照镜子”

反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制就是: 提供一套完善而强大的API“反射“类的结构. 打个比方,反射机制就像是一面镜子,而类就像是一个在照着镜子的人. 镜子(反射机制)照出(反射)了人的全貌(类的全方位的信息,例如方法,成员变量和构造器等的相关信息) 为什么要照镜子? 因为不照镜子看不清楚自己的全貌,“镜子”就是为了解决这个问题出现的(为我们提供全面分析类的能力) 好吧

2017-9-23C#笔记(类的索引,事件,运算符,this访问器,派生,分部类,抽象类,封闭类,静态类,类与结构的不同)

1.类的索引 索引是一组get和set锋访问器,支持按照饮用数组元素的方法来引用对象.索引通常便是多个数据成员,并且它总是以雷类的事例成员的方式存在.声明索引的方法: 返回类型     this  [参数列表] { Get {    } set {        } } 例如:using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplicat

类和结构(二)

二.匿名类型 var关键字用于表示隐式类型化得变量.var和new关键字一起使用时,可以创建匿名类型. 匿名类型只是一个继承自Object且没有名称的类. var caption = new {FirstName = "John",LastName="Doe"}; 这会生成一个包含FirstName,LastName属性的对象. 创建另一个对象: var doctor = new {FirstName = "James",LastName=&qu

反射获取一个类的私有方法

今天在刷面试题的时候,发现一个题目是编写程序通过反射获取一个类的私有方法,因为之前学反射的时候也学的浅,没有考虑到这样的事情.今天敲了一下,虽然也就是那么几行代码,还是磕磕绊绊的,最后终于搞定了,这里总结一下 Java反射得到一个类的私有方法 获得私有方法的流程是 (1)获取目标类 (2)获取目标方法 Method method=clazz.getDeclaredMethod(name);//可以调用类中的所有方法(不包括父类中继承的方法) Method method=clazz.getMeth