Java反射
Reflection,程序在运行期可以拿到一个对象的所有信息
类信息
Class类作用
- 每加载一个类,会先加载
.class
文件到内存,然后JVM会创建一个Class对象
与之关联
- 一个
Class对象
包含了.class
的完整信息,包括类名、包名、父类、实现的接口、所有方法、字段等
- 每个类在内存中只有一个
Class对象
.class
是懒加载的
获取Class对象
Class只能由JVM创建
1 2 3 4 5 6 7 8 9 10 11 12
| Class cls1 = String.class;
String str = "hello"; Class cls2 = str.getClass();
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2 && cls2 == cls3);
|
获取类信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public static void main(String[] args) throws ClassNotFoundException { printClassInfo(int.class); printClassInfo(String.class); printClassInfo(String[].class); }
static void printClassInfo(Class cls) { System.out.println("Class name: " + cls.getName()); System.out.println("Simple name: " + cls.getSimpleName()); if (cls.getPackage() != null) { System.out.println("Package name: " + cls.getPackage().getName()); } System.out.println("is interface: " + cls.isInterface()); System.out.println("is enum: " + cls.isEnum()); System.out.println("is array: " + cls.isArray()); System.out.println("is primitive: " + cls.isPrimitive()); }
|
获取父类
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) throws Exception { Class i = Integer.class; Class n = i.getSuperclass(); System.out.println(n);
Class o = n.getSuperclass(); System.out.println(o); System.out.println(o.getSuperclass()); } }
|
获取实现的接口
不包含父类实现的接口
1 2 3 4 5 6 7 8 9
| public class Main { public static void main(String[] args) throws Exception { Class s = Integer.class; Class[] is = s.getInterfaces(); for (Class i : is) { System.out.println(i); } } }
|
实例信息
获取字段信息(Field)
Field getField(name)
:根据字段名获取某个public的field(包括父类)
Field getDeclaredField(name)
:根据字段名获取当前类的某个field(不包括父类)
Field[] getFields()
:获取所有public的field(包括父类)
Field[] getDeclaredFields()
:获取当前类的所有field(不包括父类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Main { public static void main(String[] args) throws NoSuchFieldException { Class stdClass = Student.class; System.out.println(stdClass.getField("score")); System.out.println(stdClass.getField("name")); System.out.println(stdClass.getDeclaredField("grade")); }
class Student extends Person { public int score; private int grade; }
class Person { public String name; } }
|
Field字段包含了字段的所有信息:
getName()
:返回字段名称
getType()
:返回字段类型
getModifiers()
:返回字段的修饰符,通过int表示
获取/设置字段值
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
| public class Main { public static void main(String[] args) throws Exception { Person p = new Person("Xiao Ming"); Class c = p.getClass();
Field f = c.getDeclaredField("name"); f.setAccessible(true);
Object value = f.get(p); System.out.println(value);
f.set(p, "Xiao Hong"); System.out.println(p.getName()); } }
class Person { private String name;
public Person(String name) { this.name = name; }
public String getName() { return this.name; } }
|
获取方法(Method)
Method getMethod(name, Class...)
:获取某个public
的Method
(包括父类)
Method getDeclaredMethod(name, Class...)
:获取当前类的某个Method
(不包括父类)
Method[] getMethods()
:获取所有public
的Method
(包括父类)
Method[] getDeclaredMethods()
:获取当前类的所有Method
(不包括父类)
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
| public class Main { public static void main(String[] args) throws Exception { Class stdClass = Student.class; System.out.println(stdClass.getMethod("getScore", String.class)); System.out.println(stdClass.getMethod("getName")); System.out.println(stdClass.getDeclaredMethod("getGrade", int.class)); } }
class Student extends Person { public int getScore(String type) { return 99; } private int getGrade(int year) { return 1; } }
class Person { public String getName() { return "Person"; } }
|
调用方法
调用普通的方法
1 2 3 4 5 6 7 8 9 10 11 12
| public class Main { public static void main(String[] args) throws Exception { String s = "Hello world"; Method m = String.class.getMethod("substring", int.class); String r = (String) m.invoke(s, 6); System.out.println(r); } }
|
调用静态方法
invoke的第一个参数”实例”始终为null
1 2 3 4 5 6 7 8 9 10
| public class Main { public static void main(String[] args) throws Exception { Method m = Integer.class.getMethod("parseInt", String.class); Integer n = (Integer) m.invoke(null, "12345"); System.out.println(n); } }
|
调用私有方法
需要.setAccessible(true)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Main { public static void main(String[] args) throws Exception { Person p = new Person(); Method m = p.getClass().getDeclaredMethod("setName", String.class); m.setAccessible(true); m.invoke(p, "Bob"); System.out.println(p.name); } }
class Person { String name; private void setName(String name) { this.name = name; } }
|
调用构造方法(Constructor)
只能调用无参构造
1
| Person person = Person.class.newInstance();
|
通过Constructor调用有参构造
getConstructor(Class...)
:获取某个public
的Constructor
getDeclaredConstructor(Class...)
:获取某个Constructor
getConstructors()
:获取所有public
的Constructor
getDeclaredConstructors()
:获取所有Constructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Main { public static void main(String[] args) throws Exception { Constructor cons1 = Integer.class.getConstructor(int.class); Integer n1 = (Integer) cons1.newInstance(123); System.out.println(n1);
Constructor cons2 = Integer.class.getConstructor(String.class); Integer n2 = (Integer) cons2.newInstance("456"); System.out.println(n2); } }
|
调用私有构造方法也需要setAccessible(true)