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()
將對象轉換爲字符串。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章