Java反射(Reflection)

通过反射查看类信息

反射所有的方法,在API里边有,直接搜索Class就可以看到。在这篇博客里,我会演示一些方法的使用。

PS : API中的方法摘要放在下边了。

API查找Class
API查找Class
效果图
效果图

获得Calss对象

  1. 使用Class类得forName()静态方法。需要传入类得全限定名作为参数。
    例如:
Class.forName("reflect.TestGetClass")
  1. 调用类得class属性。
    例如:
TestGetClass.class
  1. 调用对象得getClass()方法。(所有类都有得方法)
    例如:
/*
 * new TestGetClass()——匿名实例化TestGetClass,
 * 得到TestGetClass的实例化对象,然后直接调用该对象的getClass方法
 */
new TestGetClass().getClass()

小结:第一种方式和第二种方式,都是直接根据类来获取Class对象,但第二种有以下优点:

  1. 代码更安全,程序在编译阶段就可以检查需要访问的C;ass对象是否存在。
  2. 程序性能更高,因为这种方式无需调用方法,所以性能更高。

从Class中获取信息

复制提醒:代码中有使用类的限定名的地方,复制过去以后记得改限定名

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*
 * 使用两个注释修饰该类
 * @SuppressWarnings(value="unchecked")——抑制没有进行类型检查操作的警告
 * @Deprecated——抑制警告,类加删除线,设置为过时、不建议使用
 */
@SuppressWarnings(value="unchecked")
@Deprecated
public class GetClassMessage {
	
	// 定义一个私有构造器
	private GetClassMessage() {
		
	}
	// 定义一个有参数的构造器
	public GetClassMessage(String name) {
		
	}
	// 定义一个无参的info方法
	public void info() {
		System.out.println("执行无参的info方法");
	}
	// 定义一个有参的info方法
	public void info(String str) {
		System.out.println("执行无参的info方法"
				+",参数str = "+str);
	}
	// 定义一个测试用的内部类
	class Inner{
		
	}
	
	public static void main(String[] args) throws Exception{
		// 下面代码可以获取本类对应的Class
		Class<GetClassMessage> clazz = GetClassMessage.class;
		// 获取该Class对象所对应的全部构造器
		Constructor[] ctors=clazz.getDeclaredConstructors();
		System.out.println("本类的全部构造器如下:");
		for (Constructor constructor : ctors) {
			System.out.println(constructor);
		}
		// 获取该Class对象对应类的全部public构造器
		Constructor[] publicCtors = clazz.getConstructors();
		System.out.println("本类的全部public构造器如下:");
		for (Constructor constructor : publicCtors) {
			System.out.println(constructor);
		}
		// 获取该Class对象对应类的全部public方法
		Method[] mtds = clazz.getMethods();
		System.out.println("本类的全部public方法如下:");
		for (Method method : mtds) {
			System.out.println(method);
		}
		// 获取该Class对应类的指定方法
		System.out.println("本类里带一个字符串的info方法为:"
		+ clazz.getMethod("info", String.class));
		// 获取该Class所对应类上的全部注释
		Annotation[] anns = clazz.getAnnotations();
		System.out.println("本类的全部Annotation方法如下:");
		for (Annotation annotation : anns) {
			System.out.println(annotation);
		}
		System.out.println("该Class元素上的@SuppressWarnings注释为:"
				+ clazz.getAnnotation(SuppressWarnings.class));
		// 获取该Class所对应类的全部内部类
		Class<?>[] inners = clazz.getDeclaredClasses();
		System.out.println("本类的全部内部类如下:");
		for (Class c : inners) {
			System.out.println(c);
		}
		// 使用 Class.forName 方法加载本类的 Inner 内部类
		Class inClazz = Class.forName("reflection.GetClassMessage$Inner");
		// 通过 getDeclaringClass() 访问该类所在的外部类
		System.out.println("inClazz对应类的外部类为:"+
		inClazz.getDeclaringClass());
		System.out.println("本类的包为:"+clazz.getPackage());
		System.out.println("本类的父类为:"+clazz.getSuperclass());
	
	}

执行结果:

本类的全部构造器如下:
private reflection.GetClassMessage()
public reflection.GetClassMessage(java.lang.String)
本类的全部public构造器如下:
public reflection.GetClassMessage(java.lang.String)
本类的全部public方法如下:
public static void reflection.GetClassMessage.main(java.lang.String[]) throws java.lang.Exception
public void reflection.GetClassMessage.info(java.lang.String)
public void reflection.GetClassMessage.info()
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()
本类里带一个字符串的info方法为:public void reflection.GetClassMessage.info(java.lang.String)
本类的全部Annotation方法如下:
@java.lang.Deprecated()
该Class元素上的@SuppressWarnings注释为:null
本类的全部内部类如下:
class reflection.GetClassMessage$Inner
inClazz对应类的外部类为:class reflection.GetClassMessage
本类的包为:package reflection
本类的父类为:class java.lang.Object

小结:从运行结果可以看到 @SuppressWarnings 的注释获取不到,这是因为这个注释上边有@Retention(RetentionPolicy.SOURCE) (点进源码可见),这个注释的作用是:应用改注解的注解,指能保存再源码级别上。而Class对象是再运行中获得的,所以访问不到。

使用反射生成操作对象

复制提醒:代码中有文件相对路径的地方,复制过去以后记得改路径

创建对象

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class CreateObject {

	// 定义一个对象池,前面是对象名,后边是实际对象
	private Map<String,Object> objectPool = new HashMap<>();
	/**
	 * 定义一个创建对象的方法</br>
	 * 该方法制药传入一个字符串类名,程序可以根据类名生成 Java 对象
	 * @param clazzName
	 * @return
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	private Object createObject(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		// 根据字符串来获取对应的 Class 对象
		Class<?> clazz = Class.forName(clazzName);
		// 使用clazz对应类的默认构造器创建实例
		return clazz.newInstance();
	}
	/**
	 * 该方法根据指定文件来初始化对象池</br>
	 * 他会根据配置文件来创建对象
	 * @param filePath 文件路径
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public void initPool(String filePath) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		// 从文件系统中的某个文件中获得输入字节。
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(filePath);
			// 该类主要用于读取Java的配置文件,属性列表中每个键及其对应值都是一个字符串。
			Properties props = new Properties();
			// 从输入流中读取属性列表(键和元素对)
			props.load(fis);
			
			for (String name : props.stringPropertyNames()) {
				// 每取出一对属性名——属性值对,就根据属性值创建一个对象
				// 调用 createObject 创建对象,并将对象添加到对象池中
				objectPool.put(name, createObject(props.getProperty(name)));
			}
		} catch (IOException ex) {
			System.out.println("读取" + filePath + "异常");
			ex.printStackTrace();
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch(IOException ex) {
				ex.printStackTrace();
			}
		}
	}
	/**
	 * 从对象池中返回指定对象
	 * @param name 对象名
	 * @return 指定对象
	 */
	public Object getObject(String name) {
		// 从 objectPool 中取出指定 name 对应的对象
		return objectPool.get(name);
	}
	
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		CreateObject co = new CreateObject();
		// 根据配置文件创建了两个对象
		co.initPool("src\\reflection\\obj.txt");
		// 从对象池中获取对象
		System.out.println(co.getObject("a"));
		System.out.println(co.getObject("b"));
	}
	
}

运行结果:

Tue Jun 16 20:52:04 CST 2020
javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

小结:这种是通过配置文件创建对象的,Spring框架就是采用这种方式开发的。但是,Spring采用的是XML配置文件,因为XML可以配置更多的信息。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class CreateObjectJFrame {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// 获取 JFrame 对应的 Class 对象
		Class<?> jframeClaxzz = Class.forName("javax.swing.JFrame");
		// 获取 JFrame 中带一个字符串参数的构造器
		Constructor constructor = jframeClaxzz.getConstructor(String.class);
		// 调用 Constructor 的 newInstance 方法创建对象。
		Object newInstance = constructor.newInstance("测试窗口");
		// 输出JFrame对象
		System.out.println(newInstance);
	}

}
javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=测试窗口,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

小结:这个已经知道java.swing.JFrame没必要用反射,上边只是为了演示反射创建对象,毕竟直接 new 比反射效率和性能高。

调用方法

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class ExtendeMethod {

	// 定义一个对象池,前面是对象名,后面是实际对象
	private Map<String ,Object> objectPool = new HashMap<>();
	private Properties config = new Properties();
	/**
	 * 从指定属性文件中初始化 Properties 对象
	 * @param filePath 文件路径
	 */
	public void init(String filePath) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(filePath);
			config.load(fis);
		} catch (IOException ex){
			System.out.println("读取"+filePath+"异常");
			ex.printStackTrace();
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException ex){
				ex.printStackTrace();
			}
		}
	}
	/**
	 * 创建对象
	 * @param clazzName	类名
	 * @return	生成的对象
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	private Object createObject(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		// 根据字符串来获取对应的 Class 对象
		Class<?> clazz = Class.forName(clazzName);
		// 使用clazz对应类的默认构造器创建实例
		return clazz.newInstance();
	}
	/**
	 * 该方法指定文件来初始化对象池
	 * 他会根据配置文件来创建对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public void initPool() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		for (String name : config.stringPropertyNames()) {
			/*
			 * 每取出一对属性名——属性值对,如果属性名中不包含%,
			 * 就根据属性创建一个对象
			 * 调用 createObject 创建对象,并将对象添加到兑现池中
			 */
			if (!name.contains("%")) {
				objectPool.put(name, createObject(config.getProperty(name)));
			}
		}
	}

	public void initProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		for (String name : config.stringPropertyNames()) {
			/*
			 * 每取出一对属性名——属性值对,如果属性名中不包含%,
			 * 即可认为该属性是用于为对象设置属性值,
			 * 程序将调用对应的 setter 方法来为对应属性设置值。
			 */
			if (name.contains("%")) {
				// 将配置文件中属性名按%分割
				String[] objAndProp = name.split("%");
				// 取出需要设置属性的目标对象
				Object target = getObject(objAndProp[0]);
				// 该属性对应的 setter 方法名:set + “属性的首字母大写” + 剩下部分
				String mtdName = "set" + 
						objAndProp[1].substring(0,1).toUpperCase() + 
						objAndProp[1].substring(1);
				// 通过 target 的 getClass() 获取它实现类对应的 Class 对象
				Class<?> targetClass = target.getClass();
				// 获取该属性对应的 setter 方法
				Method mtd = targetClass.getMethod(mtdName, String.class);
				/*
				 * 通过 Method 的 invoke 方法执行 setter 方法
				 * 将 config.getProperty(name) 的属性值作为调用 setter 的方法的实参
				 */
				mtd.invoke(target, config.getProperty(name));
			}
		}
	}
	/**
	 * 从 objectPool 中取出指定 name 对应的对象
	 * @param name 对象名
	 * @return
	 */
	private Object getObject(String name) {
		// 从 objectPool 中取出指定 name 对应的对象
		return objectPool.get(name);
	}

	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, InstantiationException {
		ExtendeMethod em = new ExtendeMethod();
		em.init("src\\reflection\\obj2.txt");
		em.initPool();
		em.initProperty();
		System.out.println(em.getObject("a"));
	}
}

运行结果:

javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=Test Title,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

小结:

  1. Method 的 setAccessible(boolean flag)方法,可以取消类的权限检查,取消后可以访问 private 方法。
  2. Spring 框架就是通过这种将属性值以及依赖对象都放在配置文件中进行管理,从而实现了较好的解耦。

访问属性值

import java.lang.reflect.Field;

public class VisitAttributeValue {
	
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		// 创建一个 Person 对象
		Person person = new Person();
		// 获取 Person 类对应的 Class 对象
		Class<Person> persongClazz= Person.class;
		/*
		 * 获取 Person 类名为 name 的属性
		 * 使用 getDeclaredField,表明可以获取各种访问权限控制符的 field
		 */
		Field nameField = persongClazz.getDeclaredField("name");
		// 设置通过反射访问该 Field 时取消访问权限检查
		nameField.setAccessible(true);
		// 调用 set 方法为 person 对象指定的 Field 设置值
		nameField.set(person, "Yeeku.H.Lee");
		// 获取 Person 类名为 age 的属性
		Field ageField = persongClazz.getDeclaredField("age");
		ageField.setAccessible(true);
		ageField.setInt(person, 30);
		System.out.println(person);
	}
}
class Person{
	private String name;
	private int age;
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

运行结果:

Person [name=Yeeku.H.Lee, age=30]

操作数组

import java.lang.reflect.Array;

public class UseArray {
	
	public static void main(String[] args) {
		try {
			// 创建一个元素类型为 String ,长度为 10 的数组
			Object arr = Array.newInstance(String.class, 10);
			// 依次为 arr 数组中 index 为 5、6 的元素复制
			Array.set(arr, 5, "Struts2 权威指南");
			Array.set(arr, 6, "ROR 敏捷开发最佳时间");
			// 依次取出 arr 数组中 index 为 5、6 的元素值
			Object book1 = Array.get(arr, 5);
			Object book2 = Array.get(arr, 6);
			// 输出 arr 数组中 index 为 5、6 的元素
			System.out.println(book1);
			System.out.println(book2);
		} catch (Exception e) {
			System.out.println(e);
		}
	}
}

使用反射生成JDK动态代理

使用Proxy和InvocationHandler创建动态代理

关于这个知识点,我已经写过博客,不再复写:
java开发,必须要懂的23种设计模式——代理模式(动态JDK代理模式)

动态代理和AOP

代理在AOP编程中很常用。
AOP——面向切面编程。

下边的图,仅仅是为了帮助理解AOP编程的思想,实际实现过程并不是这样。而是在代理类里边调用被代理类的方法,下边会举例。
AOP
初级需求:查看赛利亚的任务。
Seria

public interface Seria {
	String[] LINES = {
			"你好啊,我叫赛丽亚" ,
			"今天,也是充满希望的一天。" ,
			"你好啊!这里的人都叫我赛丽亚。" ,
			"看来你真的要去冒险了,不用跟我道别,我会一直陪在你身边的!" ,
			"我会一直等着你的!" ,
			"一定要记得我!" ,
			"你说,是命运让我们相遇的吗?" ,
			"我,就在这里等着你!" ,
			"看到你平安无事,我就放心了" ,
			"你还会回来吗?"};
	void say ();
	void task1 ();
	void task2 ();
	void task3 ();
}

SeriaImpl

ublic class SeriaImpl implements Seria {

	@Override
	public void say() {
		System.out.println("----");
		System.out.println(LINES[(int)(Math.random()*10)]);
		System.out.println("----");
	}

	@Override
	public void task1() {
		System.out.println("----");
		System.out.println("开始查看任务1");
		System.out.println("结束查看任务1");
		System.out.println("----");
	}

	@Override
	public void task2() {
		System.out.println("----");
		System.out.println("开始查看任务2");
		System.out.println("结束查看任务2");
		System.out.println("----");
	}

	@Override
	public void task3() {
		System.out.println("----");
		System.out.println("开始查看任务3");
		System.out.println("结束查看任务3");
		System.out.println("----");
	}

}

Ghostknight

public class Ghostknight {

	public static void main(String[] args) {
		Seria seria = new SeriaImpl();
		seria.say();
		seria.task1();
		seria.task2();
		seria.task3();

	}

}

运行结果

----
你好啊,我叫赛丽亚
----
----
开始查看任务1
结束查看任务1
----
----
开始查看任务2
结束查看任务2
----
----
开始查看任务3
结束查看任务3

需求扩展:查看任务时,输出一下被调用方法(日志)
下边开始使用JDK动态代理,运用AOP编程的思想,进行扩展。
SeriaImplProxyFactory

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SeriaImplProxyFactory {
	private Object target;

	public SeriaImplProxyFactory(Object target) {
		this.target = target;
	}

	public Object getSeriaImplProxy() {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println(method.getName()+" 方法执行前,横向插入");
				Object returnValue = method.invoke(target, args);
				System.out.println(method.getName()+" 方法执行后,横向插入");
				return returnValue;
			}
		});
	}
}

Ghostknight

public class Ghostknight {

	public static void main(String[] args) {
		Seria seria = new SeriaImpl();
		seria.say();
		seria.task1();
		seria.task2();
		seria.task3();
		
		System.out.println("======");
		
		Seria seria2 = (Seria) new SeriaImplProxyFactory(seria).getSeriaImplProxy();
		seria2.say();
		seria2.task1();
		seria2.task2();
		seria2.task3();
	}
}

运行结果:

----
你好啊!这里的人都叫我赛丽亚。
----
----
开始查看任务1
结束查看任务1
----
----
开始查看任务2
结束查看任务2
----
----
开始查看任务3
结束查看任务3
----
======
say 方法执行前,横向插入
----
我,就在这里等着你!
----
say 方法执行后,横向插入
task1 方法执行前,横向插入
----
开始查看任务1
结束查看任务1
----
task1 方法执行后,横向插入
task2 方法执行前,横向插入
----
开始查看任务2
结束查看任务2
----
task2 方法执行后,横向插入
task3 方法执行前,横向插入
----
开始查看任务3
结束查看任务3
----
task3 方法执行后,横向插入

反射和泛型

使用反射来获取泛型信息

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

public class GetGenericsMessage {
	
	private Map<String , Integer> score;
	public static void main(String[] args) throws NoSuchFieldException, SecurityException {
		Class<GetGenericsMessage> clazz = GetGenericsMessage.class;
		Field f = clazz.getDeclaredField("score");
		// 直接使用 getType() 取出 Field 类型只对普通类型的 Field 有效
		Class<?> a = f.getType();
		// 下边将看到仅输出 java.util.Map
		System.out.println("score 的类型时:"+a);
		// 获得 Field 实例  f 的泛型类型
		Type gType = f.getGenericType();
		// 如果 gType 类型时 ParameterizedType 对象
		if(gType instanceof ParameterizedType) {
			// 强制类型转换
			ParameterizedType pType = (ParameterizedType)gType;
			// 获取原来类型
			Type rType = pType.getRawType();
			System.out.println("原始类型是:"+rType);
			// 获取泛型类型的泛型参数
			Type[] tArgs = pType.getActualTypeArguments();
			System.out.println("泛型类型是:");
			for (int i = 0; i < tArgs.length; i++) {
				System.out.println("第"+i+"个泛型类型是:"+tArgs[i]);
			}
		} else {
			System.out.println("获取泛型类型出错!");
		}
	}
}

运行结果:

score 的类型时:interface java.util.Map
原始类型是:interface java.util.Map
泛型类型是:
第0个泛型类型是:class java.lang.String1个泛型类型是:class java.lang.Integer

Class API 方法摘要

方法及参数 描述
Class<? extends U> asSubclass(Class clazz)
强制转换该 Class 对象,以表示指定的 class 对象所表示的类的一个子类。
T cast(Object obj)
将一个对象强制转换成此 Class 对象所表示的类或接口。
boolean desiredAssertionStatus()
如果要在调用此方法时将要初始化该类,则返回将分配给该类的断言状态。
static Class<?> forName(String className)
返回与带有给定字符串名的类或接口相关联的 Class 对象。
static Class<?> forName(String name, boolean initialize, ClassLoader loader)
使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
<A extends Annotation> getAnnotation(Class annotationClass)
A 如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
Annotation[] getAnnotations()
返回此元素上存在的所有注释。
String getCanonicalName()
返回 Java Language Specification 中所定义的底层类的规范化名称。
Class<?>[] getClasses()
返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class 对象所表示的类的成员的所有公共类和接口。
ClassLoader getClassLoader()
返回该类的类加载器。
Class<?> getComponentType()
返回表示数组组件类型的 Class。
Constructor getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。
Class<?>[] getDeclaredClasses()
返回 Class 对象的一个数组,这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口。
Constructor getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Class<?> getDeclaringClass()
如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class 对象表示该对象的声明类。
Class<?> getEnclosingClass()
返回底层类的立即封闭类。
Constructor<?> getEnclosingConstructor()
如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回 Constructor 对象,它表示底层类的立即封闭构造方法。
Method getEnclosingMethod()
如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法。
T[] getEnumConstants()
如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。
Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
Type[] getGenericInterfaces()
返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现。
Type getGenericSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。
Class<?>[] getInterfaces()
确定此对象所表示的类或接口实现的接口。
Method getMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
int getModifiers()
返回此类或接口以整数编码的 Java 语言修饰符。
String getName()
以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
Package getPackage()
获取此类的包。
ProtectionDomain getProtectionDomain()
返回该类的 ProtectionDomain。
URL getResource(String name)
查找带有给定名称的资源。
InputStream getResourceAsStream(String name)
查找具有给定名称的资源。
Object[] getSigners()
获取此类的标记。
String getSimpleName()
返回源代码中给出的底层类的简称。
Class<? super T> getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
TypeVariable<Class>[] getTypeParameters()
按声明顺序返回 TypeVariable 对象的一个数组,这些对象表示用此 GenericDeclaration 对象所表示的常规声明来声明的类型变量。
boolean isAnnotation()
如果此 Class 对象表示一个注释类型则返回 true。
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
boolean isAnonymousClass()
当且仅当底层类是匿名类时返回 true。
boolean isArray()
判定此 Class 对象是否表示一个数组类。
boolean isAssignableFrom(Class<?> cls)
判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
boolean isEnum()
当且仅当该类声明为源代码中的枚举时返回 true。
boolean isInstance(Object obj)
判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。
boolean isInterface()
判定指定的 Class 对象是否表示一个接口类型。
boolean isLocalClass()
当且仅当底层类是本地类时返回 true。
boolean isMemberClass()
当且仅当底层类是成员类时返回 true。
boolean isPrimitive()
判定指定的 Class 对象是否表示一个基本类型。
boolean isSynthetic()
如果此类是复合类,则返回 true,否则 false。
T newInstance()
创建此 Class 对象所表示的类的一个新实例。
String toString()
将对象转换为字符串。

猜你喜欢

转载自blog.csdn.net/qq_42909053/article/details/106789493