文章目錄
- 反射的泛型就是用 `? `來描述
- 反射與類的操作 (取得父類資訊)
- 取得父類資訊
- 1. 獲得本類的包名稱:
- 2. 取得父類的Class 物件
- 3. 取得父類介面
- 案例: 使用上述方法
- 反射與類的操作 (反射呼叫構造)
- 反射呼叫構造
- 1. 取得指定引數型別的構造
- 2. 取得類中的所有構造
- `實體化物件: `
- 案例: 取得類中的所有構造方法資訊.
- 改進: 使用getName() 方法取得構造方法完整資訊
- 案例實作: 自己拼湊構造方法
- 重點:
- 案例: 觀察 Class 實體化物件的問題
- 案例: 要通過 Constructor 類實體化物件
反射的泛型就是用 ?來描述
反射與類的操作 (取得父類資訊)
利用反射可以做出一個物件所具備的所有操作行為, 而且最關鍵的是這一切的操作都可以基于Object型別進行.
取得父類資訊
在Java 里面任何的程式類實際上都要求一定會有一個父類, 在 Class類里面就可以通過此方式來取得父類或者是實作的父介面, 有如下的倆個方法提供:
1. 獲得本類的包名稱:
public Package getPackage()
2. 取得父類的Class 物件
public Class<? super T> getSuperclass()
3. 取得父類介面
public Class<?>[] getInterfaces()
通過反射可以取得類結構上的所有關鍵資訊
案例: 使用上述方法
package com.record;
interface IMessage{
}
interface IFruit{
}
class Person implements IFruit,IMessage{
public void print() {
}
}
public class TestDemo {
public static void main(String[] args) {
// 方式一
Person person = new Person();
person.print();
//反射實作
Class<?> cls = Person.class;
System.out.println(cls.getName()); // 獲得本物件所屬的全類名
System.out.println(cls.getPackage().getName()); // 獲得本類的包名稱
System.out.println(cls.getSuperclass().getName()); // 獲得父類的Class物件
Class<?> itf [] = cls.getInterfaces(); // 獲得父類所有介面
for (int x = 0; x < itf.length; x++) {
System.out.println(itf[x].getName());
}
}
}
反射與類的操作 (反射呼叫構造)
反射呼叫構造
一個類中可以存在多個構造方法, 那么如果要想取得類中構造的呼叫, 就可以使用 Class 類提供的兩個方法
1. 取得指定引數型別的構造
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException,
SecurityException
2. 取得類中的所有構造
public Constructor<?>[] getConstructors()
throws SecurityException
以上兩個方法回傳的都是 java.lang.reflect.Constructor<T> 類的實體化物件, 這個類里面要重點關注一個方法:
實體化物件:
public T newInstance(Object... initargs)
throws InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
案例: 取得類中的所有構造方法資訊.
package com.record;
import java.lang.reflect.Constructor;
class Person{
public Person() {}
public Person(String name) {}
public Person(String name, int age) {}
}
public class TestDemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
Constructor<?> conts[] = cls.getConstructors();
for (int x = 0; x < conts.length; x++) {
System.out.println(conts[x].toString());
}
}
}

以上操作是直接利用了 Constructor 類中的 toString () 方法 取得構造方法的完整資訊, 而如果只是使用 getName() 方法就會比較麻煩了.

所以, getName() 只能取出 方法的名稱.
改進: 使用getName() 方法取得構造方法完整資訊
使用方法一: 獲得修飾符的資訊 (依然是 java.lang.reflect.Constructor<T> 類中)
public int getModifiers()
結合 Modifier 類中的 toString() 方法實作
public static String toString(int mod)
使用方法二 : 獲得方法中的詳細引數資訊
public Class<?>[] getParameterTypes()
使用方法三 : 獲得方法中的例外拋出資訊
public Class<?>[] getExceptionTypes()
案例實作: 自己拼湊構造方法
package com.record;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
class Person{
public Person() throws Exception {}
public Person(String name) throws RuntimeException,Exception {}
public Person(String name, int age) throws Exception {}
}
public class TestDemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
Constructor<?> conts[] = cls.getConstructors();
for (int x = 0; x < conts.length; x++) {
System.out.print(Modifier.toString(conts[x].getModifiers())+" ");
System.out.print(conts[x].getName()+"(");
Class<?> params [] = conts[x].getParameterTypes();
for (int y = 0; y < params.length; y++) {
System.out.print(params[y].getName());
if (y< params.length -1) {
System.out.print(",");
}
}
System.out.print(")");
Class<?> exps [] = conts[x].getExceptionTypes();
if (exps.length > 0) { // 表示有例外
System.out.print(" throws ");
for (int i = 0; i < exps.length; i++) {
System.out.print(exps[i].getName());
if (i<exps.length -1) {
System.out.print(",");
}
}
System.out.println();
}
}
}
}

重點:
要理解為什么在定義簡單 java 類的時候一定要保留有一個無參構造
案例: 觀察 Class 實體化物件的問題
package com.record;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls = Person.class;
System.out.println(cls.newInstance());
}
}

Class 類通過反射實體化物件的時候, 只能夠呼叫類中的無參構造, 那么如果類中沒有無參構造, 無法使用 Class類操作, 只能通過明確的構造呼叫執行實體化處理
案例: 要通過 Constructor 類實體化物件
package com.record;
import java.lang.reflect.Constructor;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls = Person.class;
// 在明確表示取得指定引數型別的構造方法物件
Constructor<?> cont = cls.getConstructor(String.class, int.class);
System.out.println(cont.newInstance("張三",15));
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/243569.html
標籤:java
