Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以得到任意一个对象所属的类的信息,可以调用任意一个类的成员变量和方法,可以获取任意一个对象属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。
优点:实现动态创建对象和编译(即动态编译)
实例化Class对象共有以下三种方式:
(1)根据类名获取:类名.class
(2)根据对象获取:对象.getClass()
(3)根据全限定类名获取:Class.forName("全限定类名")
反射的应用:
通过反射可以得到一个类的完整结构,包括类的构造方法、类的属性、类的方法
以如下A类为例
(1)Constructor:表示类中的构造方法。
常用方法
无参构造实例化对象
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("A");
A a = null;
try {
a = (A)c1.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
a.setAge(18);
a.setName("jack");
System.out.println(a);
}
A{name='jack', age=18}
有参构造实例化对象
(1)通过Class类中的getConstructors()方法获取本类中的全部构造方法。
(2) 向构造方法中传递一个对象数组,对象数组里面包含构造方法中所需的各个参数。
(3)通过Constructor类实例化对象。
try {
Class<?> c1 = Class.forName("A");
Constructor<?> cons[] = c1.getConstructors();
//数组下标表示调用第几个构造方法
A a1 = (A)cons[0].newInstance();
System.out.println(a1);
A a2 = (A)cons[1].newInstance("jack",18);
System.out.println(a2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
A{name='null', age=0}
A{name='jack', age=18}
(2)Field:表示类中的属性。
通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。
getFields() getFied(String name) getDeclaredFieds() getDeclaredFied(String name)
访问访问指定的成员变量,可以通过该成员变量的名称来访问。
常用方法
public static void main(String[] args) throws ClassNotFoundException{
Class<?> c2 = new A().getClass();
Field f[] = c2.getDeclaredFields();// 取得本类属性
for (int i = 0; i < f.length; i++) {
int mod = f[i].getModifiers();// 得到修饰符数字
String modifier = Modifier.toString(mod);// 取得属性的修饰符
Class<?> r = f[i].getType();// 取得属性的类型
String typeName = r.getName();
String fieldName = f[i].getName();// 取得属性名称
System.out.println("本类属性:" + modifier + " " + typeName + " " +
fieldName + ";");
}
}
本类属性:private java.lang.String name;
本类属性:private int age;
(3)Method:表示类中的方法。
通过下列一组方法访问方法时,将返回Method类型或数组
getMethods()
getMethod(String name,Class<?>... parameterTypes)
getDeclaredMethods()
getDeclaredMethod(String name,Class<?>... parameterTypes)
以下案例获取ArrayList类中方法
try {
Class<?> c = Class.forName("java.util.ArrayList");
Method[] methods = c.getMethods();
for (int i = 0; i < methods.length; i++) {
String methodName = methods[i].getName();
int methodModifiers = methods[i].getModifiers();
Class<?>[] parameterTypes = methods[i].getParameterTypes();
Class<?>[] exceptionTypes = methods[i].getExceptionTypes();
System.out.println(
"方法名:" + methodName +
", 修饰符:" + methodModifiers +
", 全部参数类型:" + parameterTypes +
", 全部抛出异常:" + exceptionTypes);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
(4)获取实现的类与接口
要取得一个类所实现的全部接口,必须使用Class中的getInterfaces()方法。
要取得一个类所继承的父类,调用getSuperclass()方法。
public static void main(String[] args) {
Class<?> c = ArrayList.class;
Class<?>[] interfaces = c.getInterfaces();
Class<?> Super = c.getSuperclass();
for (int i = 0; i < interfaces.length; i++) {
System.out.println(
"ArrayList类实现的接口名称:"+ interfaces[i]+ c.getName()
);
System.out.println("父类名称:"+Super.getName());
}
}
java反射问题可随时私信我,觉得有用就点点赞,谢谢
CSDN@看我眼神行事516为我另一个小号,我直接将其文章搬运过来,并且将小号的文章已经删除,并非抄袭他人,谢谢。