1 Class
$\text {java.lang.Class}$
反射的基础,是类的类型标识。
构造器是私有的,Class
对象只能由 JVM 创建:
1 2 3 private Class (ClassLoader loader) { classLoader = loader; }
提供了获取类相关信息的核心方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public String getName () public native int getModifiers () public native Class<? super T> getSuperclass()public Class<?>[] getInterfaces()public Constructor<?>[] getDeclaredConstructors()public Method[] getDeclaredMethods()public Field[] getDeclaredFields()
反射的核心功能:
1 2 3 4 5 6 7 8 public T newInstance () public Method getMethod (String name, Class<?>... parameterTypes) public Field getField (String name) public Constructor<T> getConstructor (Class<?>... parameterTypes)
类加载时,JVM 创建对应的 Class
对象。
获取 Class
对象有以下三种主要方式:
通过类的 Class
属性:
1 Class<String> clazz1 = String.class;
通过对象的 getClass()
方法:
1 2 String str = "Hello World" ;Class<? extends String > clazz2 = str.getClass();
通过 Class.forName()
静态方法:
1 2 3 4 5 try { Class<?> clazz3 = Class.forName("java.lang.String" ); } catch (ClassNotFoundException e) { e.printStackTrace(); }
示例:比较 getSimpleName
,getName
,getCanonicalName
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.solisamicus;public class Test { private class inner { } public static void main (String[] args) throws ClassNotFoundException { System.out.println(Test.class.getSimpleName()); System.out.println(Test.class.getName()); System.out.println(Test.class.getCanonicalName()); System.out.println(inner.class.getSimpleName()); System.out.println(inner.class.getName()); System.out.println(inner.class.getCanonicalName()); System.out.println(args.getClass().getSimpleName()); System.out.println(args.getClass().getName()); System.out.println(args.getClass().getCanonicalName()); } } Test com.solisamicus.Test com.solisamicus.Test inner com.solisamicus.Test$inner com.solisamicus.Test.inner String[] [Ljava.lang.String; java.lang.String[]
2 Constructor
$\text {java.lang.reflect.Constructor}$
1 2 3 4 Constructor<?>[] getConstructors() Constructor<?>[] getDeclaredConstructors() Constructor<T> getConstructor (Class<?>... params) Constructor<T> getDeclaredConstructor (Class<?>... params)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.solisamicus;public class User { private String name; private int age; public User (String name) { this .name = name; } private User (String name, int age) { this .name = name; this .age = age; } @Override public String toString () { return "User{" + "age=" + age + ", name='" + name + '\'' + '}' ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.solisamicus;import java.lang.reflect.Constructor;public class Main { public static void main (String[] args) { try { Class<User> userClass = User.class; System.out.println("=== constructors(public) ===" ); Constructor<?>[] constructors = userClass.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } System.out.println("\n=== constructors(public & private) ===" ); Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors(); for (Constructor<?> constructor : declaredConstructors) { System.out.println(constructor); } System.out.println("\n=== specific constructor(public) ===" ); Constructor<User> constructor = userClass.getConstructor(String.class); System.out.println(constructor); User user1 = constructor.newInstance("jack" ); System.out.println(user1); System.out.println("\n=== specific constructor(public & private) ===" ); Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class, int .class); declaredConstructor.setAccessible(true ); User user2 = declaredConstructor.newInstance("Bob" , 20 ); System.out.println(user2); } catch (Exception e) { e.printStackTrace(); } } }
=== constructors(public) ===
public com.solisamicus.User(java.lang.String)
=== constructors(public & private) ===
public com.solisamicus.User(java.lang.String)
private com.solisamicus.User(java.lang.String,int)
=== specific constructor(public) ===
public com.solisamicus.User(java.lang.String)
User{age=0, name=‘jack’}
=== specific constructor(public & private) ===
User{age=20, name=‘Bob’}
3 Field
$\text {java.lang.reflect.Field}$
1 2 3 4 Field[] getFields() Field[] getDeclaredFields() Field getField (String name) Field getDeclaredField (String name)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.solisamicus;class Animal { public String species; protected int age; private String name; public Animal (String species, int age, String name) { this .species = species; this .age = age; this .name = name; } } class Dog extends Animal { public String color; private String breed; public Dog (String species, int age, String name, String color, String breed) { super (species, age, name); this .color = color; this .breed = breed; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package com.solisamicus;import java.lang.reflect.Field;public class Main { public static void main (String[] args) { try { Class<Dog> dogClass = Dog.class; Dog dog = new Dog ("Canine" , 3 , "Max" , "Brown" , "Labrador" ); System.out.println("=== fields(public), include inheritance fields ===" ); Field[] fields = dogClass.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("\n=== fields(public & private), not include inheritance fields ===" ); Field[] declaredFields = dogClass.getDeclaredFields(); for (Field field : declaredFields) { System.out.println(field); } System.out.println("\n=== specific field(public), include inheritance fields ===" ); try { Field speciesField = dogClass.getField("species" ); System.out.println("Public field 'species': " + speciesField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'species'" ); } try { Field ageField = dogClass.getField("age" ); System.out.println("Protected field 'age': " + ageField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'age'" ); } try { Field nameField = dogClass.getField("name" ); System.out.println("Private field 'name': " + nameField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'name'" ); } try { Field colorField = dogClass.getField("color" ); System.out.println("Public field 'color': " + colorField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'color'" ); } try { Field breedField = dogClass.getField("breed" ); System.out.println("Private field 'breed': " + breedField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'breed'" ); } System.out.println("\n=== specific field(public & private), not include inheritance fields ===" ); try { Field speciesField = dogClass.getDeclaredField("species" ); System.out.println("Public field 'species': " + speciesField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'species'" ); } try { Field ageField = dogClass.getDeclaredField("age" ); System.out.println("Protected field 'age': " + ageField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'age'" ); } try { Field nameField = dogClass.getDeclaredField("name" ); System.out.println("Private field 'name': " + nameField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'name'" ); } try { Field colorField = dogClass.getDeclaredField("color" ); System.out.println("Public field 'color': " + colorField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'color'" ); } try { Field breedField = dogClass.getDeclaredField("breed" ); breedField.setAccessible(true ); System.out.println("Private field 'breed': " + breedField.get(dog)); } catch (NoSuchFieldException e) { System.out.println("Cannot access field 'breed'" ); } } catch (Exception e) { e.printStackTrace(); } } }
=== fields(public), include inheritance fields ===
public java.lang.String com.solisamicus.Dog.color
public java.lang.String com.solisamicus.Animal.species
=== fields(public & private), not include inheritance fields ===
public java.lang.String com.solisamicus.Dog.color
private java.lang.String com.solisamicus.Dog.breed
=== specific field(public), include inheritance fields ===
Public field ‘species’: Canine
Cannot access field ‘age’
Cannot access field ‘name’
Public field ‘color’: Brown
Cannot access field ‘breed’
=== specific field(public & private), not include inheritance fields ===
Cannot access field ‘species’
Cannot access field ‘age’
Cannot access field ‘name’
Public field ‘color’: Brown
Private field ‘breed’: Labrador
总结:
修饰符
所属类
getFields()
getDeclaredFields()
getField()
getDeclaredField()
public
父类
✓
✗
✓
✗
protected
父类
✗
✗
✗
✗
private
父类
✗
✗
✗
✗
public
子类
✓
✓
✓
✓
private
子类
✗
✓
✗
✓*
✓ 表示可以访问
✗ 表示不能访问
✓* 表示需要设置 setAccessible(true) 才能访问
4 Method
$\text {java.lang.reflect.Method}$
1 2 3 4 Method[] getMethods() Method[] getDeclaredMethods() Method getMethod (String name, Class<?>... params) Method getDeclaredMethod (String name, Class<?>... params)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.solisamicus;class Animal { public String species; protected int age; private String name; public Animal (String species, int age, String name) { this .species = species; this .age = age; this .name = name; } public void makeSound () { System.out.println("Animal makes sound" ); } protected void eat () { System.out.println("Animal eats" ); } private void sleep () { System.out.println("Animal sleeps" ); } } class Dog extends Animal { public String color; private String breed; public Dog (String species, int age, String name, String color, String breed) { super (species, age, name); this .color = color; this .breed = breed; } @Override public void makeSound () { System.out.println("Dog barks" ); } public void fetch () { System.out.println("Dog fetches" ); } private void wagTail () { System.out.println("Dog wags tail" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 package com.solisamicus;import java.lang.reflect.Method;public class Main { public static void main (String[] args) { try { Class<Dog> dogClass = Dog.class; Dog dog = new Dog ("Canine" , 3 , "Max" , "Brown" , "Labrador" ); System.out.println("=== methods(public), include inheritance methods ===" ); Method[] methods = dogClass.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("\n=== methods(public & private), not include inheritance methods ===" ); Method[] declaredMethods = dogClass.getDeclaredMethods(); for (Method method : declaredMethods) { System.out.println(method); } System.out.println("\n=== specific method(public), include inheritance methods ===" ); try { Method parentMakeSound = dogClass.getMethod("makeSound" ); System.out.println("Parent's overridden public method 'makeSound': " ); parentMakeSound.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'makeSound' from parent" ); } try { Method parentEat = dogClass.getMethod("eat" ); System.out.println("Parent's protected method 'eat': " ); parentEat.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'eat' from parent" ); } try { Method parentSleep = dogClass.getMethod("sleep" ); System.out.println("Parent's private method 'sleep': " ); parentSleep.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'sleep' from parent" ); } try { Method fetch = dogClass.getMethod("fetch" ); System.out.println("Child's public method 'fetch': " ); fetch.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'fetch'" ); } try { Method wagTail = dogClass.getMethod("wagTail" ); System.out.println("Child's private method 'wagTail': " ); wagTail.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'wagTail'" ); } System.out.println("\n=== specific method(public & private), not include inheritance methods ===" ); try { Method parentMakeSound = dogClass.getDeclaredMethod("makeSound" ); System.out.println("Parent's overridden public method 'makeSound': " ); parentMakeSound.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'makeSound' from parent" ); } try { Method parentEat = dogClass.getDeclaredMethod("eat" ); System.out.println("Parent's protected method 'eat': " ); parentEat.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'eat' from parent" ); } try { Method parentSleep = dogClass.getDeclaredMethod("sleep" ); System.out.println("Parent's private method 'sleep': " ); parentSleep.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'sleep' from parent" ); } try { Method fetch = dogClass.getDeclaredMethod("fetch" ); System.out.println("Child's public method 'fetch': " ); fetch.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'fetch'" ); } try { Method wagTail = dogClass.getDeclaredMethod("wagTail" ); wagTail.setAccessible(true ); System.out.println("Child's private method 'wagTail': " ); wagTail.invoke(dog); } catch (NoSuchMethodException e) { System.out.println("Cannot access method 'wagTail'" ); } } catch (Exception e) { e.printStackTrace(); } } }
=== methods(public), include inheritance methods ===
public void com.solisamicus.Dog.makeSound()
public void com.solisamicus.Dog.fetch()
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()
=== methods(public & private), not include inheritance methods ===
public void com.solisamicus.Dog.makeSound()
private void com.solisamicus.Dog.wagTail()
public void com.solisamicus.Dog.fetch()
=== specific method(public), include inheritance methods ===
Parent’s overridden public method ‘makeSound’:
Dog barks
Cannot access method ‘eat’ from parent
Cannot access method ‘sleep’ from parent
Child’s public method ‘fetch’:
Dog fetches
Cannot access method ‘wagTail’
=== specific method(public & private), not include inheritance methods ===
Parent’s overridden public method ‘makeSound’:
Dog barks
Cannot access method ‘eat’ from parent
Cannot access method ‘sleep’ from parent
Child’s public method ‘fetch’:
Dog fetches
Child’s private method ‘wagTail’:
Dog wags tail
总结:
修饰符
所属类
getMethods()
getDeclaredMethods()
getMethod()
getDeclaredMethod()
public
父类/子类
✓
✓
✓
✓
protected
父类
✗
✗
✗
✗
private
父类
✗
✗
✗
✗
public
子类
✓
✓
✓
✓
private
子类
✗
✓
✗
✓*
✓ 表示可以访问
✗ 表示不能访问
✓* 表示需要设置 setAccessible(true) 才能访问