在本教程中,我們將學(xué)習(xí)反射,這是Java編程中的一個(gè)特性,它允許我們檢查和修改類、方法等。
在Java中,反射允許我們在運(yùn)行時(shí)檢查和操作類、接口、構(gòu)造函數(shù)、方法和字段。
在學(xué)習(xí)Java反射之前,我們需要了解一個(gè)名為Class的Java類。
Java中有一個(gè)名為Class的類,該類在運(yùn)行時(shí)保留有關(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)的接口的信息。此方法返回一個(gè)接口數(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)建一個(gè)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)建一個(gè)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)建一個(gè)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è)類中的所有構(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ù)個(gè)數(shù): " + c.getParameterCount()); } } catch(Exception e) { e.printStackTrace(); } } }
輸出結(jié)果
構(gòu)造函數(shù)名稱: Dog 修飾符: public 參數(shù)個(gè)數(shù): 0 構(gòu)造函數(shù)名稱: Dog 修飾符: public 參數(shù)個(gè)數(shù): 1 構(gòu)造函數(shù)名稱: Dog 修飾符: private 參數(shù)個(gè)數(shù): 2