Java反射机制(二):通过反射取得类的结构

简介:

在反射运用过程中,如果你想得到一个类的完整结构,那么就要使用到java.lang.reflect包中的几个类:

· Constructor  表示类中的构造方法
· Field  表示类中的属性
· Method 表示类中的方法

接下来,我们讲讲,如何通过这些API,去获取一个类的完整性结构。

首先,我们定义一个类:

package com.chen.yuan.vo;
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 ;
	}
};

一、 通过反射取得类所实现的全部接口


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


二、 取得类所继承的父类


package com.chen.yuan.vo;
public class GetSuperClassDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		// 声明Class对象
		try{
			c1 = Class.forName("com.chen.yuan.vo.Person") ;	// 实例化对象
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Class<?> c2 = c1.getSuperclass() ;	// 取得父类
		System.out.println("父类名称:" + c2.getName()) ;
	}
};

输出: 父类名称:java.lang.Object


三、取得类中的全部构造方法

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

输出:

构造方法:public com.chen.yuan.vo.Person(java.lang.String,int)
构造方法:public com.chen.yuan.vo.Person(java.lang.String)
构造方法:public com.chen.yuan.vo.Person()

以上直接打印出构造方法,调用的是Constructor类中 的toString()方法。

Constructor类中存在了一下几个几个方法:

· public int getModifiers()取得修饰符

· public String getName()取得方法名称

· public Class<?>[] getParameterTypes()取得参数的类型

public class GetConstructorDemo02{
	public static void main(String args[]){
		Class<?> c1 = null ;		// 声明Class对象
		try{
			c1 = Class.forName("com.chen.yuan.vo.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 com.chen.yuan.vo.Person(java.lang.String arg0,int arg0){}
构造方法:1 com.chen.yuan.vo.Person(java.lang.String arg1){}
构造方法:1 com.chen.yuan.vo.Person(){}

观察输出,我们发现,所有的修饰符变成了数字,我们肯定不懂这些个数字是什么意思,那么接下来,让我们还原修饰符。此时,我们需要借助Modifier类完成,此类定义在java.lang.reflect包中,我们可以直接使用Modifier类中的toString(int mod)方法完成还原修饰符的操作。

先看一下Modifier类中的toString(int mod)方法的源码:

 /**
     * The {@code int} value representing the {@code public}
     * modifier.
     */
    public static final int PUBLIC           = 0x00000001;


    /**
     * The {@code int} value representing the {@code private}
     * modifier.
     */
    public static final int PRIVATE          = 0x00000002;


    /**
     * The {@code int} value representing the {@code protected}
     * modifier.
     */
    public static final int PROTECTED        = 0x00000004;


    /**
     * The {@code int} value representing the {@code static}
     * modifier.
     */
    public static final int STATIC           = 0x00000008;


    /**
     * The {@code int} value representing the {@code final}
     * modifier.
     */
    public static final int FINAL            = 0x00000010;


    /**
     * The {@code int} value representing the {@code synchronized}
     * modifier.
     */
    public static final int SYNCHRONIZED     = 0x00000020;


    /**
     * The {@code int} value representing the {@code volatile}
     * modifier.
     */
    public static final int VOLATILE         = 0x00000040;


    /**
     * The {@code int} value representing the {@code transient}
     * modifier.
     */
    public static final int TRANSIENT        = 0x00000080;


    /**
     * The {@code int} value representing the {@code native}
     * modifier.
     */
    public static final int NATIVE           = 0x00000100;


    /**
     * The {@code int} value representing the {@code interface}
     * modifier.
     */
    public static final int INTERFACE        = 0x00000200; 
public static String toString(int mod) {
        StringBuffer sb = new StringBuffer();
        int len;

        if ((mod & PUBLIC) != 0)        sb.append("public ");
        if ((mod & PROTECTED) != 0)     sb.append("protected ");
        if ((mod & PRIVATE) != 0)       sb.append("private ");

        /* Canonical order */
        if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
        if ((mod & STATIC) != 0)        sb.append("static ");
        if ((mod & FINAL) != 0)         sb.append("final ");
        if ((mod & TRANSIENT) != 0)     sb.append("transient ");
        if ((mod & VOLATILE) != 0)      sb.append("volatile ");
        if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
        if ((mod & NATIVE) != 0)        sb.append("native ");
        if ((mod & STRICT) != 0)        sb.append("strictfp ");
        if ((mod & INTERFACE) != 0)     sb.append("interface ");

        if ((len = sb.length()) > 0)    /* trim trailing space */
            return sb.toString().substring(0, len-1);
        return "";
    }

通过源码,我们应当很容易的发现,在Modifier类中的toString(int mod)方法中,我们进行了转换的操作。

public class GetConstructorDemo03{
	public static void main(String args[]){
		Class<?> c1 = null ;		// 声明Class对象
		try{
			c1 = Class.forName("com.chen.yuan.vo.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 com.chen.yuan.vo.Person(java.lang.String arg0,int arg0){}
构造方法:public com.chen.yuan.vo.Person(java.lang.String arg1){}
构造方法:public com.chen.yuan.vo.Person(){}


四、 取得全部方法

要想取得一个类中的全部方法,可以通过Class类中的getDeclaredMethods()方法,此方法返回一个Method类的对象数组,然后我们可以通过Method类,去进一步得到方法的详细信息。

public class GetMethodDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		// 声明Class对象
		try{
			c1 = Class.forName("com.chen.yuan.vo.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) + " ") ;	// 输出修饰符
			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 void sayChina()
public class java.lang.String sayHello(java.lang.String arg0,int arg1)
public void setAge(int arg0)
public int getAge()
public final void wait(long arg0,int arg1) throws java.lang.InterruptedException,
public final native void wait(long arg0) throws java.lang.InterruptedException
public final void wait() 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()


五、 取得类中的属性

Class类中提供了两种不同的操作,可以获得Field:

1) 得到实现的接口或父类中的公共属性: public Field[] getFields() throws SecurityException

2) 得到本类中的全部属性: public Field[] getDeclaredFields() throws SecurityException

public class GetFieldDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		// 声明Class对象
		try{
			c1 = Class.forName("com.chen.yuan.vo.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 ;


相关文章
|
30天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
28天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
1月前
|
Java 程序员
深入理解Java异常处理机制
Java的异常处理是编程中的一块基石,它不仅保障了代码的健壮性,还提升了程序的可读性和可维护性。本文将深入浅出地探讨Java异常处理的核心概念、分类、处理策略以及最佳实践,旨在帮助读者建立正确的异常处理观念,提升编程效率和质量。
143 1
|
1月前
|
Java 开发者 UED
深入探索Java中的异常处理机制##
本文将带你深入了解Java语言中的异常处理机制,包括异常的分类、异常的捕获与处理、自定义异常的创建以及最佳实践。通过具体实例和代码演示,帮助你更好地理解和运用Java中的异常处理,提高程序的健壮性和可维护性。 ##
65 2
|
1月前
|
Java 开发者
Java中的异常处理机制深度剖析####
本文深入探讨了Java语言中异常处理的重要性、核心机制及其在实际编程中的应用策略,旨在帮助开发者更有效地编写健壮的代码。通过实例分析,揭示了try-catch-finally结构的最佳实践,以及如何利用自定义异常提升程序的可读性和维护性。此外,还简要介绍了Java 7引入的多异常捕获特性,为读者提供了一个全面而实用的异常处理指南。 ####
65 2
|
1月前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
1月前
|
开发框架 安全 Java
Java 反射机制:动态编程的强大利器
Java反射机制允许程序在运行时检查类、接口、字段和方法的信息,并能操作对象。它提供了一种动态编程的方式,使得代码更加灵活,能够适应未知的或变化的需求,是开发框架和库的重要工具。
71 4
|
2月前
|
运维 Java 编译器
Java 异常处理:机制、策略与最佳实践
Java异常处理是确保程序稳定运行的关键。本文介绍Java异常处理的机制,包括异常类层次结构、try-catch-finally语句的使用,并探讨常见策略及最佳实践,帮助开发者有效管理错误和异常情况。
133 5
|
1月前
|
Java 程序员 UED
深入理解Java中的异常处理机制
本文旨在揭示Java异常处理的奥秘,从基础概念到高级应用,逐步引导读者掌握如何优雅地管理程序中的错误。我们将探讨异常类型、捕获流程,以及如何在代码中有效利用try-catch语句。通过实例分析,我们将展示异常处理在提升代码质量方面的关键作用。
54 3
|
2月前
|
JSON Java 程序员
Java|如何用一个统一结构接收成员名称不固定的数据
本文介绍了一种 Java 中如何用一个统一结构接收成员名称不固定的数据的方法。
40 3

热门文章

最新文章