获取到Class对象之后,就可以利用Class对象获取和操作类的属性、构造器、方法、父类和接口了。
所有的方法都可以查java.lang.Class的api文档。
以下逐一介绍:
1.属性
通过Class对象获取类的属性:
//获取所有公共的属性
Field[] getFields();
//获取所有的属性(包含四种修饰符修饰的)
Field[] getDeclaredFields();
//获取指定的某一个公有属性
Field getField("属性名字");
//获取指定的某一个属性(包含四种修饰符修饰的)
Field getDeclaredField("属性名字")
获取到Field对象或者数组之后,Field类也有以下常用方法:
//获取属性名
String getName();
//给属性赋值
void set(Object obj, Object value);
//获取属性的值
Object get(Object obj); //如果想获取私有的,就要打破封装setAccessible(true);--->缺点:不安全
//获取属性的数据类型
Class<?> getType();
//获取类的修饰符
int getModifiers();
获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:
Modifier.toString(参数为getModifiers()的返回值);
综合例子:
User类:具有四个修饰权限的属性
package com.dh.field;
public class User {
public String name;
int age;
protected int no;
private char sex;
}
测试类:
package com.dh.field;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ResourceBundle;
public class ReflectField {
public static void main(String[] args) {
//获取类名
ResourceBundle bundle = ResourceBundle.getBundle("className");
String name = bundle.getString("className");
// System.out.println(name);
Class c = null;
try {
//获取Class
c = Class.forName(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取类的简单名称
String simpleName = c.getSimpleName();
//获取类的所有公共属性
System.out.println("------------"+simpleName+"类的所有公共属性:");
Field[] fields = c.getFields();
for (Field field : fields) {
//获取属性的名称
System.out.println(field.getName());
}
//获取类的所有属性
System.out.println("------------"+simpleName+"类的所有属性:");
Field[] fields1 = c.getDeclaredFields();
for (Field field : fields1) {
//获取属性的修饰符、数据类型、名称
System.out.println(Modifier.toString(field.getModifiers())
+"\t" +field.getType().getSimpleName()
+"\t"+field.getName());
}
//获取指定的公共属性
System.out.println("------------公共的属性为:");
try {
Field name1 = c.getField("name");
System.out.println(name1.getName());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
//获取指定的属性(四种权限)
Field sex = null;
//创建一个对象
Object o = null;
try {
o = c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
try {
sex = c.getDeclaredField("sex");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
try {
//给私有属性赋值需要先打破封装
sex.setAccessible(true);
sex.set(o,'女');
System.out.println("------------给"+sex.getName()+"添加属性成功!");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//获取属性值
try {
Object o1 = sex.get(o);
System.out.println("------------"+sex.getName()+"的属性值为:");
System.out.println(o1);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
结果:
------------User类的所有公共属性:
name
------------User类的所有属性:
public static String name
int age
protected int no
private char sex
------------公共的属性为:
name
------------给sex添加属性成功!
------------sex的属性值为:
女
2.构造方法
通过Class对象获取类的构造方法:
//获取所有公共的构造方法
Constructor<T>[] getConstructors();
//获取所有的构造方法(包含四种修饰符修饰的)
Constructor<T>[] getDeclaredConstructors();
//获取指定的某一个构造方法
Constructor<T> getConstructor(类<?>... parameterTypes);
//获取指定的某一个构造方法(包含四种修饰符修饰的)
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes);
//获取数据类型
String getTypeName();
获取到Constructor对象或者数组之后,Constructor类也有以下常用方法:
//获取构造方法的修饰符
int getModifiers();
//获取构造方法的参数
Class<>[] getParameterTypes();
//创建对象
T newInstance(Object... initargs); //如果想利用私有的构造方法,就要打破封装setAccessible(true);--->缺点:不安全
获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:
Modifier.toString(参数为getModifiers()的返回值);
综合例子:
User类:
package com.dh.constructor;
public class User {
public static String name;
int age;
protected int no;
private char sex;
public User() {
}
public User(int age) {
this.age = age;
}
private User(int age, int no, char sex) {
this.age = age;
this.no = no;
this.sex = sex;
}
}
测试类:
package com.dh.constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ResourceBundle;
public class ReflectConstructor {
//为了代码好看些,将所有的异常都采取throws的方式
public static void main(String[] args) throws Exception {
//获取类名
ResourceBundle bundle = ResourceBundle.getBundle("className");
String name = bundle.getString("className2");
//获取Class对象
Class c = Class.forName(name);
//获取公共的构造器
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
//获取构造器中的修饰符
System.out.print(Modifier.toString(constructor.getModifiers()));
System.out.print("\t");
//获取构造方法名
System.out.print(c.getSimpleName());
//获取构造方法参数
Class[] parameterTypes = constructor.getParameterTypes();
for (Class parameterType : parameterTypes) {
//获取参数的类型
System.out.print("\t");
System.out.print(parameterType.getTypeName());
}
System.out.println();
}
//获取所有的构造器
Constructor[] declaredConstructors = c.getDeclaredConstructors();
System.out.println(declaredConstructors.length);
//获取指定的公共构造器
Constructor constructor = c.getConstructor(int.class);
//通过指定的构造器创建对象
//Constructor类newInstance()的没有过时!!!
Object o = constructor.newInstance(1);
System.out.println(o);
//获取指定的私有的构造器
Constructor declaredConstructor = c.getDeclaredConstructor(int.class, int.class,char.class);
//开放私有构造方法权限
declaredConstructor.setAccessible(true);
Object o1 = declaredConstructor.newInstance(1, 1,'女');
System.out.println(o1);
}
}
结果:
public User
public User int
3
com.dh.constructor.User@13fee20c
com.dh.constructor.User@4e04a765
3.方法
通过Class对象获取类的方法:
//获取所有公共的方法
Method[] getMethods();
//获取所有的方法(包含四种修饰符修饰的)
Method[] getDeclaredMethods();
//获取指定的某一个方法
Method getMethod(String name,类<?>... parameterTypes);
//获取指定的某一个方法(包含四种修饰符修饰的)
Method getMethod(String name,类<?>... parameterTypes);
//获取数据类型
String getTypeName();
获取到Method对象或者数组之后,Method类也有以下常用方法:
//获取构造方法的修饰符
int getModifiers();
//获取方法的返回值类型
Class getReturnType();
//获取方法名
String getName();
//获取方法的参数
Class<>[] getParameterTypes();
//执行方法
Object invoke(Object obj, Object... args);//如果执行私有的方法,就要打破封装setAccessible(true);--->缺点:不安全
获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:
Modifier.toString(参数为getModifiers()的返回值);
综合例子:
User:
package com.dh.method;
public class User {
public void sayHi() {
System.out.println("hello");
}
protected static String Print(String s) {
return s;
}
private int add(int a, int b) {
return a + b;
}
}
测试:
package com.dh.method;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.TypeVariable;
import java.util.ResourceBundle;
public class ReflectMethod {
public static void main(String[] args) throws Exception {
//获取类名
ResourceBundle bundle = ResourceBundle.getBundle("className");
String name = bundle.getString("className3");
//获取Class对象
Class c = Class.forName(name);
//获取公有的方法(包含九个Object类的)
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.print(method.getName()+"\t");
}
System.out.println();
//获取所有的方法
Method[] declaredMethods = c.getDeclaredMethods();
for (Method method : declaredMethods) {
//获取方法的修饰符
System.out.print(Modifier.toString(method.getModifiers())+"\t");
//获取方法的返回值
System.out.print(method.getReturnType().getSimpleName()+"\t");
//获取方法名
System.out.print(method.getName()+"\t");
//获取方法的参数
Class[] parameterTypes = method.getParameterTypes();
for (Class type : parameterTypes) {
System.out.print(type.getSimpleName()+"\t");
}
System.out.println();
}
//获取某个指定的公共方法
Method sayHi = c.getDeclaredMethod("sayHi");
System.out.println(sayHi);
//获取某个指定的私有方法
Method add = c.getDeclaredMethod("add", int.class, int.class);
//调用某个方法
//参数需要对象和实参
Object o = c.getConstructor().newInstance();
//调用私有方法需要先设置权限
add.setAccessible(true);
Object result = add.invoke(o, 1, 1);
System.out.println(result);
}
}
结果:
sayHi wait wait wait equals toString hashCode getClass notify notifyAll
private int add int int
public void sayHi
protected static String Print String
public void com.dh.method.User.sayHi()
2
4.父类和接口
一个类的父类只有一个。通过Class对象获取:
类<? super T> getSuperClass();
但是可以实现多个接口:
类<?>[] getInterfaces();
**再使用getName()获得类和接口的名称(完整的)。
虽然方法很多,但是都有异曲同工之妙,并且很多都能够自己猜测到方法的名称。