Begin
反射机制是在运行状态中:
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
反射提供的功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
获取反射对象
package reflect;
public class reflectDemo1 {
public static void main(String[] args) {
// 获取反射对象(反射入口)
// 1. Class.forName(全类名)
try {
Class<?> perClazz1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 2. 类名.class
Class<?> perClazz2 = reflect.Person.class;
// 3. 对象.getClass()
Person per = new Person();
Class<?> perClazz3 = per.getClass();
}
}
package reflect;
public class Person implements MyInterface {
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public static void staticMethod() {
System.out.println("staticMethod");
}
public Person(int id) {
this.id = id;
}
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void privateMethod() {
System.out.println("privateMethod");
}
private void privateMethod(String s) {
System.out.println(s);
}
private int id;
private String name;
private int age;
@Override
public void interfaceMethod() {
System.out.println("interfaceMethod");
}
}
Java泛型中的通配符
<?>
称为非受限通配,其实就相当于<? extends Object>
,可以表示任何一种对象类型<? extends T>
称为受限通配,表示需要的是T或者T的子类型<? super T>
称为下限通配,表示需要的是T的父类型
断言
assert <boolean表达式>
如果<boolean表达式>为true
,则程序继续执行。如果为false
,则程序抛出AssertionError
,并终止执行。assert <boolean表达式> : <错误信息表达式>
如果<boolean表达式>
为true
,则程序继续执行。
如果为 false
,则程序抛出 java.lang.AssertionError
,并输入 <错误信息表达式>
。
<错误信息表达式>
表示一个基本类型、表达式或者是一个 Object
,用于在失败时输出错误信息。
获取Class的内容
// Class入口
Class<?> perClazz1 = null;
try {
perClazz1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 获取所有公共方法(本类及父类,接口中的方法且符合访问修饰符规则)
assert perClazz1 != null;
Method[] methods = perClazz1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
// 获取所有接口
Class<?>[] interfaces = perClazz1.getInterfaces();
for (Class<?> inter : interfaces) {
System.out.println(inter);
}
// 获取所有父类(单继承)
Class<?> superclass = perClazz1.getSuperclass();
System.out.println(superclass);
// 获取所有构造方法
Constructor<?>[] constructors = perClazz1.getConstructors();
// 获取所有公共属性(包括父类,符合访问修饰符)
Field[] fields = perClazz1.getFields();
// 获取当前类的所有方法(当前类,包括private)
Method[] methods1 = perClazz1.getDeclaredMethods();
// 获取当前反射所代表类(接口)的对象的实例
Object instance = null;
try {
instance = perClazz1.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Person per = (Person) instance;
assert per != null;
per.interfaceMethod();
操作对象
// 操作获取实例的对象
per.setAge(6);
per.setName("zs");
// 操作属性
Field idField = perClazz1.getDeclaredField("id");
// 修改属性的访问权限
idField.setAccessible(true);
idField.set(per, 1);
// 操作方法
Method method = perClazz1.getDeclaredMethod("privateMethod", null);
method.setAccessible(true);
method.invoke(per, null);
// 有参
method = perClazz1.getDeclaredMethod("privateMethod", String.class);
method.setAccessible(true);
method.invoke(per, "zs");
操作构造方法
// 操作构造方法
Constructor<?>[] constructors1 = perClazz1.getDeclaredConstructors();
for(Constructor<?> constructor: constructors1)
System.out.println(constructor);
// 获取指定构造方法(反射中基本类型和包装类型不同)
// 如果是private要用perClazz1.getDeclaredConstructor()
Constructor<?> constructor = perClazz1.getConstructor(int.class);
System.out.println(constructor);
// 产生对象
Person instance1 = (Person) constructor.newInstance(10);
通过反射运行配置文件内容
配置文件class.txt:
className = reflect.Student
methodName = staticMethod
Properties prop = new Properties();
prop.load(new FileReader("class.txt"));
String classname = prop.getProperty("classname");
String methodname = prop.getProperty("methodname");
Class<?> perClazz = null;
try {
perClazz = Class.forName(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method method = perClazz.getMethod(methodname);
method.invoke(perClazz.newInstance());
越过泛型检查
ArrayList<Integer> list = new ArrayList<>();
list.add(123);
list.add(3);
list.add(2);
// list.add("zs") ;
Class<?> listClazz = list.getClass();
Method method = listClazz.getMethod("add", Object.class);
method.invoke(list, "zs");
System.out.println(list);
通用的set方法
public class PropertyUtil {
public static void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Class<?> clazz = obj.getClass();
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true);
field.set(obj, value);
}
}
调用:
Person per = new Person();
PropertyUtil.setProperty(per, "name", "zs");
动态一维数组
Scanner in = new Scanner(System.in);
System.out.println("Input Type:");
String type = in.nextLine();
System.out.println("Input num:");
int num = in.nextInt();
Class<?> c = Class.forName(type);
Object arr = Array.newInstance(c, num);
Array.set(arr, 0, "zs");
System.out.println(Array.get(arr, 0));
动态二维数组
Class c = Integer.class;
int[] dim = {4, 4};
Object o = Array.newInstance(c, dim);
// 第二行
Object arr2 = Array.get(o, 2);
// 第二行第一列赋值
Array.set(arr2, 1, 666);
System.out.println(Array.get(arr2, 1));
版权属于:moluuser
本文链接:https://archive.moluuser.com/archives/41/
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。