反射的概念
在运行过程中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称java语言的反射机制。
使用反射获取类的信息
Class :反射的核心类,可以获取类的属性、方法等内容信息
Field :表示类的属性、可以获取和设置类中属性的信息
Method :表示类的方法,可以用来获取类中方法的信息或者执行方法
Constructor :表示类的构造方法
/**
* 所有的类都是Class类的对象,Class则称为该类的类类型
*/
public class ReflexClass {
public static void main(String[] args) throws ClassNotFoundException {
// 第一种 : 通过类型的静态class属性获取类类型
Class<String> stringClass = String.class;
// 第二种 : 通过类对象的getClass()方法获取类类型
Class<? extends Integer> integerClass = new Integer(1).getClass();
// 第三种 : 通过Class类的forName方法通过全类名加载类类型
Class<?> doubleClass = Class.forName("java.lang.Double");
// 一个类只有一个类类型,即所有的类类型相同
}
}
import java.lang.reflect.*;
/**
* 测试反射
*/
public class ReflexUtil {
// 获取反射类的构造方法
public void getConstructors(String reflex) throws ClassNotFoundException {
// 获取反射类的类类型
Class<?> classType = Class.forName(reflex);
// 获取构造方法
Constructor<?>[] constructors = classType.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
// 输出访问修饰符
System.out.print(Modifier.toString(constructors[i].getModifiers()) + " " + constructors[i].getDeclaringClass().getSimpleName() + "(");
// 获取参数信息
Parameter[] parameters = constructors[i].getParameters();
for (int j = 0; j < parameters.length; j++) {
// 获取参数类型和参数名
System.out.print(parameters[j].getType().getSimpleName());
if (j != parameters.length - 1) {
System.out.print(",");
}
}
System.out.println(")");
}
}
// 获取反射类的属性
public void getFields(String reflex) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 获取反射类的类类型
Class<?> classType = Class.forName(reflex);
// 获取所有的属性
Field[] fields = classType.getDeclaredFields();
// 遍历所有的属性
for (Field field : fields) {
// 输出所有的属性信息
//System.out.println(field);
// 访问权限 + 参数类型 + 属性名
System.out.println(Modifier.toString(field.getModifiers()) + " " +
field.getType().getSimpleName() + " " + field.getName());
}
}
// 获取反射类的方法
public void getMethods(String reflex) throws ClassNotFoundException {
// 获取反射类的类类型
Class<?> classType = Class.forName(reflex);
// 获取方法数组
Method[] methods = classType.getDeclaredMethods();
// 输出方法信息
for (Method method : methods) {
//System.out.println(method);
// 输出访问控制符 + 方法类型 + 方法名
System.out.print(Modifier.toString(method.getModifiers()) + " " + method.getReturnType().getSimpleName()
+ " " + method.getName() + " " + "(");
// 获取方法的参数
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
// 获取参数类型和参数名
System.out.print(parameters[i].getType().getSimpleName());
if (i != parameters.length - 1) {
System.out.print(",");
}
}
System.out.println(")");
}
}
}
反射的操作
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 反射
*/
public class Test {
public static void main(String[] args) throws Exception {
// 获取反射类的类类型
Class<?> stringClass = Class.forName("java.lang.String");
// 通过反射创建对象 : 获取构造方法,根据构造方法创建对象
Object o = stringClass.getConstructor().newInstance();
// 通过反射后获取类的属性
Field field = stringClass.getDeclaredField("hash");
// 设置属性的访问权限
field.setAccessible(true);
// 访问对象属性的值
System.out.println(field.get(o));
// 通过反射获取类的方法
Method method = stringClass.getMethod("concat", String.class);
// 调用类的方法
Object invoke = method.invoke(o, "墨渐生微");
// 测试
System.out.println(invoke);
}
}
反射的应用
import javax.sound.midi.SysexMessage;
import java.io.*;
import java.lang.reflect.Field;
/**
* 需求 : 将创建的对象的值以键值对形式存入文件中,
* 针对不同的对象则需要实现不同的方法,而通过反射则可解决所有的操作
*/
public class TestFile {
// 将反射对象的值写入文件
public static boolean objectToFile(Object obj, String path) {
// 创建文件对象
File file = new File(path);
// 创建文件输出流
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file,true));
// 获取obj对象的类类型
Class<?> classType = obj.getClass();
// 获取该类的所有属性
Field[] fields = classType.getDeclaredFields();
// 写出类类型
bufferedOutputStream.write((classType.getSimpleName()+"\r\n").getBytes());
// 遍历属性
for (int i = 0; i < fields.length; i++) {
// 获取属性的名称
String field = fields[i].getName();
// 设置访问属性的权限
fields[i].setAccessible(true);
// 获取属性的值
Object value = null;
value = fields[i].get(obj);
// 初始化要输出的资源
String source = field + " : " + value;
// 以字节数组写出
bufferedOutputStream.write(source.getBytes());
bufferedOutputStream.write("\r\n".getBytes());
}
// 写出换行
bufferedOutputStream.write("\r\n".getBytes());
// 刷新流
bufferedOutputStream.flush();
bufferedOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}