在本教程中,我們將學(xué)習(xí)反射,這是Java編程中的一個特性,它允許我們檢查和修改類、方法等。
在Java中,反射允許我們在運(yùn)行時檢查和操作類、接口、構(gòu)造函數(shù)、方法和字段。
在學(xué)習(xí)Java反射之前,我們需要了解一個名為Class的Java類。
Java中有一個名為Class的類,該類在運(yùn)行時保留有關(guān)對象和類的所有信息。
Class對象描述了特定類的屬性。該對象用于執(zhí)行反射。
我們可以創(chuàng)建Class的對象,通過:
使用forName()方法
forName()接受字符串參數(shù)(類的名稱)并返回Class對象。返回的對象引用字符串指定的類。例如,
Class Dog { }
Class c1 = Class.forName("Dog");使用getClass()方法
getClass()方法使用特定類的對象來創(chuàng)建新的對象Class。例如,
Dog d1 = new Dog() Class c1 = d1.getClass();
使用.class
我們還可以使用.class擴(kuò)展名創(chuàng)建Class對象。例如,
Class c1 = Dog.class;
創(chuàng)建Class對象后,我們可以使用這些對象執(zhí)行反射。
我們可以使用Class的getInterfaces()方法來收集類實(shí)現(xiàn)的接口的信息。此方法返回一個接口數(shù)組。
import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
public void display();
}
interface Mammal {
public void makeSound();
}
class Dog implements Animal, Mammal {
public void display() {
System.out.println("I am a dog.");
}
public void makeSound() {
System.out.println("Bark bark");
}
}
class ReflectionDemo {
public static void main(String[] args) {
try {
//創(chuàng)建一個Dog類的對象
Dog d1 = new Dog();
//使用getClass()創(chuàng)建Class對象
Class obj = d1.getClass();
//查找由Dog實(shí)現(xiàn)的接口
Class[] objInterface = obj.getInterfaces();
for(Class c : objInterface) {
//打印接口名稱
System.out.println("Interface Name: " + c.getName());
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
Interface Name: Animal Interface Name: Mammal
類Class的方法getSuperclass()可用于獲取有關(guān)特定類的超類的信息。
而且,Class提供了一種getModifier()方法,該方法以整數(shù)形式返回class的修飾符。
import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
public void display();
}
public class Dog implements Animal {
public void display() {
System.out.println("I am a dog.");
}
}
class ReflectionDemo {
public static void main(String[] args) {
try {
//創(chuàng)建一個Dog類的對象
Dog d1 = new Dog();
//使用getClass()創(chuàng)建Class對象
Class obj = d1.getClass();
//以整數(shù)形式獲取Dog的訪問修飾符
int modifier = obj.getModifiers();
System.out.println("修飾符: " + Modifier.toString(modifier));
//找到Dog的超類
Class superClass = obj.getSuperclass();
System.out.println("Superclass: " + superClass.getName());
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
修飾符: public Superclass: Animal
該軟件包java.lang.reflect提供了可用于操作類成員的類。例如,
方法類 - 提供有關(guān)類中方法的信息
字段類 - 提供有關(guān)類中字段的信息
構(gòu)造函數(shù)類 - 提供有關(guān)類中構(gòu)造函數(shù)的信息
我們可以使用Field類提供的各種方法檢查和修改類的不同字段。
getFields() - 返回該類及其超類的所有公共字段
getDeclaredFields() - 返回類的所有字段
getModifier() - 以整數(shù)形式返回字段的修飾符
set(classObject,value) - 使用指定的值設(shè)置字段的值
get(classObject) - 獲取字段的值
setAccessible(boolean) - 使私有字段可訪問
注意:如果我們知道字段名稱,則可以使用
getField("fieldName") - 從類返回名稱為fieldName的公共字段。
getDeclaredField("fieldName") - 從類返回名稱為fieldName的字段。
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
public String type;
}
class ReflectionDemo {
public static void main(String[] args) {
try{
Dog d1 = new Dog();
//創(chuàng)建Class對象
Class obj = d1.getClass();
//操縱Dog類的公共字段type
Field field1 = obj.getField("type");
//設(shè)置字段的值
field1.set(d1, "labrador");
//通過轉(zhuǎn)換成字符串來獲取字段的值
String typeValue = (String)field1.get(d1);
System.out.println("type: " + typeValue);
//獲取類型的訪問修飾符
int mod1 = field1.getModifiers();
String modifier1 = Modifier.toString(mod1);
System.out.println("修飾符: " + modifier1);
System.out.println(" ");
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
type: labrador 修飾符: public
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
private String color;
}
class ReflectionDemo {
public static void main(String[] args) {
try {
Dog d1 = new Dog();
//創(chuàng)建類Class對象
Class obj = d1.getClass();
//訪問私有字段
Field field2 = obj.getDeclaredField("color");
//使私有字段可訪問
field2.setAccessible(true);
//設(shè)置color值
field2.set(d1, "brown");
// get the value of type converting in String
String colorValue = (String)field2.get(d1);
System.out.println("color: " + colorValue);
//獲取color的訪問修飾符
int mod2 = field2.getModifiers();
String modifier2 = Modifier.toString(mod2);
System.out.println("modifier: " + modifier2);
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
color: brown modifier: private
像字段一樣,我們可以使用Method類提供的各種方法來檢查類的不同方法。
getMethods() - 返回該類及其超類的所有公共方法
getDeclaredMethod() - 返回該類的所有方法
getName() - 返回方法的名稱
getModifiers() - 以整數(shù)形式返回方法的訪問修飾符
getReturnType() - 返回方法的返回類型
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
public void display() {
System.out.println("I am a dog.");
}
protected void eat() {
System.out.println("I eat dog food.");
}
private void makeSound() {
System.out.println("Bark Bark");
}
}
class ReflectionDemo {
public static void main(String[] args) {
try {
Dog d1 = new Dog();
//創(chuàng)建一個Class對象
Class obj = d1.getClass();
//使用getDeclaredMethod()獲取所有方法
Method[] methods = obj.getDeclaredMethods();
//獲取方法的名稱
for(Method m : methods) {
System.out.println("方法名稱: " + m.getName());
//獲取方法的訪問修飾符
int modifier = m.getModifiers();
System.out.println("修飾符: " + Modifier.toString(modifier));
//獲取方法的返回類型
System.out.println("Return Types: " + m.getReturnType());
System.out.println(" ");
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
方法名稱: display 修飾符: public Return type: void 方法名稱: eat 修飾符: protected 返回類型: void 方法名稱: makeSound 修飾符: private 返回類型: void
我們還可以使用Constructor類提供的各種方法檢查類的不同構(gòu)造函數(shù)。
getConstructors() - 返回該類的所有公共構(gòu)造函數(shù)以及該類的超類
getDeclaredConstructor() -返回所有構(gòu)造函數(shù)
getName() - 返回構(gòu)造函數(shù)的名稱
getModifiers() - 以整數(shù)形式返回構(gòu)造函數(shù)的訪問修飾符
getParameterCount() - 返回構(gòu)造函數(shù)的參數(shù)數(shù)量
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
public Dog() {
}
public Dog(int age) {
}
private Dog(String sound, String type) {
}
}
class ReflectionDemo {
public static void main(String[] args) {
try {
Dog d1 = new Dog();
Class obj = d1.getClass();
//使用getDeclaredConstructor()獲取一個類中的所有構(gòu)造函數(shù)
Constructor[] constructors = obj.getDeclaredConstructors();
for(Constructor c : constructors) {
//獲取構(gòu)造函數(shù)的名稱
System.out.println("構(gòu)造函數(shù)名稱: " + c.getName());
//獲取構(gòu)造函數(shù)的訪問修飾符
int modifier = c.getModifiers();
System.out.println("修飾符: " + Modifier.toString(modifier));
//獲取構(gòu)造函數(shù)中的參數(shù)數(shù)量
System.out.println("參數(shù)個數(shù): " + c.getParameterCount());
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}輸出結(jié)果
構(gòu)造函數(shù)名稱: Dog 修飾符: public 參數(shù)個數(shù): 0 構(gòu)造函數(shù)名稱: Dog 修飾符: public 參數(shù)個數(shù): 1 構(gòu)造函數(shù)名稱: Dog 修飾符: private 參數(shù)個數(shù): 2