Java 反射
Posted Shen_JC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 反射相关的知识,希望对你有一定的参考价值。
看了很多关于反射的文章和例子,却从没有自己好好总结总结。Let’s do it。
反射相关的类和方法
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
获取Class的三种方式
/**
* 获取Class的三种方式
*/
public static void testGetClass()
Class<?> c1 = null;
Class<?> c2 = null;
Class<?> c3 = null;
try
// 第一种方式
c1 = Class.forName("com.example.java.Employee");
catch (ClassNotFoundException e)
System.out.println("没有找到Employee类!");
e.printStackTrace();
// 第二种方式
c2 = Employee.class;
// 第三种方式
Employee employee = new Employee();
c3 = employee.getClass();
System.out.println("类名称, Name:" + c1.getName() + " , SimpleName:" + c1.getSimpleName());
System.out.println("类名称, Name:" + c2.getName() + " , SimpleName:" + c2.getSimpleName());
System.out.println("类名称, Name:" + c3.getName() + " , SimpleName:" + c3.getSimpleName());
运行结果:
类名称, Name:com.example.java.Employee , SimpleName:Employee
类名称, Name:com.example.java.Employee , SimpleName:Employee
类名称, Name:com.example.java.Employee , SimpleName:Employee
通过Class来创建对象
public static void newInstanceFromClass()
Class<?> c = null;
try
c = Class.forName("com.example.java.Employee");
catch (ClassNotFoundException e)
e.printStackTrace();
try
// Class.newInstance()方法会调用类的无参构造函数,所以类一定要有无参构造函数,要不然有出错。
Employee employee = (Employee) c.newInstance();
employee.setName("LiLei");
employee.setAge(20);
System.out.println(employee);
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
【运行结果】
[ Name:LiLei, mAddress:null, mAge:20, mPhoneNumber:null ]
通过Class获取并使用类的构造函数
/**
* 通过Class获取类的构造函数,包含修饰符、名字、参数类型
*/
public static void testGetConstructors()
Class<?> c = null;
try
c = Class.forName("com.example.java.Employee");
catch (ClassNotFoundException e)
e.printStackTrace();
Employee employee1 = null;
Employee employee2 = null;
// 获取所有的构造函数
Constructor<?> constructors[] = c.getConstructors();
StringBuilder sb = new StringBuilder();
for (Constructor constructor : constructors)
//获得构造函数的修饰符,例如public,static等等
sb.append(Modifier.toString(constructor.getModifiers()) + " ");
// 获取构造函数的名字
sb.append(constructor.getName());
// 获取构造函数中的参数,如果没有参数,则返回length为0的数组。
Class[] types = constructor.getParameterTypes();
sb.append(" ( ");
for (Class type : types)
sb.append(type.getSimpleName()); // 获取参数的类型名字
sb.append(" ");
sb.append(" ) ");
sb.append("\\r\\n");
System.out.println(sb.toString());
// 调用构造行数来初始化对象
try
employee1 = (Employee) constructors[0].newInstance("Lucy", "USA", 29, "1892222222");
employee2 = (Employee) constructors[1].newInstance();
employee2.setName("Jack");
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();
System.out.println(employee1);
System.out.println(employee2);
通过Class获取类实现的接口
/**
* 通过Class获取类实现的接口
*/
public static void testGetInterfaces()
Class<?> c = null;
try
c = Class.forName("com.example.java.Employee");
catch (ClassNotFoundException e)
e.printStackTrace();
// 获取实现的接口
Class[] interfaces = c.getInterfaces();
StringBuilder sb = new StringBuilder();
sb.append("实现的接口有: ");
for (Class i :interfaces)
sb.append(i.getName());
sb.append(" ");
System.out.println(sb);
通过Class获取类继承的父类
/**
* 通过Class获取类继承的父类
*/
public static void testGetSuperclass()
Class<?> c = null;
try
c = Class.forName("com.example.java.Engineer");
catch (ClassNotFoundException e)
e.printStackTrace();
// 获取父类
Class<?> parent = c.getSuperclass();
System.out.println("继承的父类:" + parent.getName());
通过Class获取类的属性变量
/**
* 通过Class获取类的属性变量
*/
public static void testGetFields()
Class<?> c = null;
try
c = Class.forName("com.example.java.Engineer");
catch (ClassNotFoundException e)
e.printStackTrace();
StringBuilder sb = new StringBuilder();
// getFields() 返回本类或者本接口中的属性字段,不包含父类或者接口中的。
Field[] fields = c.getDeclaredFields();
sb.append("本类或本接口的属性字段:\\n");
for (Field field : fields)
// 属性字段的修饰符
sb.append(Modifier.toString(field.getModifiers()) + " ");
// 属性字段的类型
sb.append(field.getType().getSimpleName() + " ");
// 属性字段的名字
sb.append(field.getName());
sb.append("\\n");
// getFields() 返回可以访问的public的属性字段,包括本类和来自父类或者接口中的public的。
fields = c.getFields();
sb.append("public的属性字段:\\n");
for (Field field : fields)
sb.append(Modifier.toString(field.getModifiers()) + " ");
sb.append(field.getType().getSimpleName() + " ");
sb.append(field.getName());
sb.append("\\n");
try
Field field = c.getDeclaredField("isJunior");
sb.append(field.getName());
catch (NoSuchFieldException e)
e.printStackTrace();
System.out.println(sb);
通过Class获取类的方法
public static void testGetMethods()
Class<?> c = null;
try
c = Class.forName("com.example.java.Engineer");
catch (ClassNotFoundException e)
e.printStackTrace();
StringBuilder sb = new StringBuilder();
sb.append("本类或本接口的方法:\\n");
Method[] declaredMethods = c.getDeclaredMethods();
for (Method method : declaredMethods)
// 方法修饰符
sb.append(Modifier.toString(method.getModifiers()) + " ");
// 方法返回类型
sb.append(method.getReturnType().getName() + " ");
// 方法名字
sb.append(method.getName() + " ");
sb.append("(");
// 获取方法的所有参数
for (Class type : method.getParameterTypes())
sb.append(type.getName());
sb.append(" ");
sb.append(") \\n");
sb.append("所有public的方法:\\n");
// 返回可以访问的public的方法,包括本类和来自父类或者接口中的public的。
Method[] methods = c.getMethods();
for (Method method : methods)
sb.append(Modifier.toString(method.getModifiers()) + " ");
sb.append(method.getReturnType().getName() + " ");
sb.append(method.getName() + " ");
sb.append("(");
for (Class type : method.getParameterTypes())
sb.append(type.getName());
sb.append(" ");
sb.append(")");
// 获取方法会抛出的Exception的异常类型
Class[] exceptionTypes = method.getExceptionTypes();
if (exceptionTypes.length > 0)
sb.append(" throws ");
for (Class type : exceptionTypes)
sb.append(type.getName());
sb.append(" ");
sb.append("\\n");
System.out.println(sb);
通过Class修改类的变量
/**
* 通过Class修改类的变量
*/
public static void testModifyFiled()
Class<?> c = null;
Object object = null;
try
c = Class.forName("com.example.java.Engineer");
object = c.newInstance();
catch (ClassNotFoundException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
try
Field field1 = c.getDeclaredField("isJunior");
Field field2 = c.getField("mNickName");
field1.setBoolean(object, true); // 修改属性变量
field2.set(object, "NICE"); // 修改属性变量
System.out.println(field1.getBoolean(object) + " " + field2.get(object));
catch (NoSuchFieldException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
System.out.println(object.toString());
通过Class来调用类的方法
/**
* 通过Class来调用类的方法
*/
public static void testCallMethod()
Class<?> c = null;
Object object = null;
try
c = Class.forName("com.example.java.Engineer");
object = c.newInstance();
catch (ClassNotFoundException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
try
Method method1 = c.getDeclaredMethod("setmLevel", int.class); // 获取本类中“setmLevel”的方法
method1.invoke(object, 4); // 调用“setmLevel”方法
Method method2 = c.getMethod("setName", String.class); // 获取父类中public的“setName”的方法
method2.invoke(object, "Jonson"); // 调用“setName”方法
catch (NoSuchMethodException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
System.out.println(object.toString());
以上是关于Java 反射的主要内容,如果未能解决你的问题,请参考以下文章