二十一、反射
« 上一篇
个人整理非商业用途,欢迎探讨与指正!!
21.1什么是类对象
类的对象:基本某个类,使用new创建出来的对象,也被称为实例对象
类对象(Class):类加载时的产物,封装了所有类的公共信息(类名,父类,接口,包,属性,构造,方法等)
每个类加载到内存时,只能生成唯一的一个类对象(Class对象)
21.2类对象的获取
java中提供了三种获取方案
public class Demo01 {
public static void main(String[] args) {
// 1.Object中的getClass方法
Dog dog = new Dog();
Class<? extends Dog> class1 = dog.getClass();
System.out.println(class1);
// 2.通过类名.class的形式
Class<? extends Dog> class2 = Dog.class;
System.out.println(class2);
// 一类只有一个Class对象
System.out.println(class1 == class2);
System.out.println(String.class);
System.out.println(Comparable.class);
// 基本类型的类对象
System.out.println(int.class);
System.out.println(double.class);
System.out.println(boolean.class);
// 3.使用全限定名 作用:1.触发类的加载 2.获取类对象
try {
Class<?> forName = Class.forName("java.lang.String");
System.out.println(forName);
// 若限定名错误,则会抛出类未找到异常
forName = Class.forName("java.lang.String123");
System.out.println(forName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Dog {
}
21.3类对象的常用方法
Class的API
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException {
// 获取类对象 文件中有的类是可以直接使用的
Class<?> forName = Class.forName("java.lang.String");
// 获取全限定名
System.out.println(forName.getName());
// 获取类名
System.out.println(forName.getSimpleName());
// 获取父类
System.out.println(forName.getSuperclass());
// 获取类加载器
System.out.println(forName.getClassLoader());
// 实现的接口
Class<?>[] interfaces = forName.getInterfaces();
System.out.println(Arrays.toString(interfaces));
// 获取包的信息
System.out.println(forName.getPackage());
// 获取public属性
Field[] fields = forName.getFields();
System.out.println(Arrays.toString(fields));
// 获取所有属性 暴力反射
fields = forName.getDeclaredFields();//d ker lai er
System.out.println(Arrays.toString(fields));
// 获取public方法
Method[] methods = forName.getMethods();
System.out.println(Arrays.toString(methods));
// 获取所有方法
methods = forName.getDeclaredMethods();
System.out.println(Arrays.toString(methods));
// 获取public构造
Constructor<?>[] constructors = forName.getConstructors();
System.out.println(Arrays.toString(constructors));
// 获取所有构造
constructors = forName.getDeclaredConstructors();
System.out.println(Arrays.toString(constructors));
}
}
public class Demo03 {
// 可以反射得到的Class对象,进行创建对象
public static void main(String[] args) throws Exception {
Class<?> forName = Class.forName("java.lang.String");
// 使用java.lang.String的空构造创建对象
Object newInstance = forName.newInstance();
System.out.println(newInstance.equals(""));
}
}
21.4Field类
类对象中的属性
public class Demo04 {
// com.qf.test.Student
public static void main(String[] args) throws Exception {
// Class类对象
Class<?> forName = Class.forName("com.qf.test.Student");
// 通过forName创建Student的空对象
Object obj = forName.newInstance();
// 获取public属性
Field field = forName.getField("balance");
// 为属性赋值 balance属性开始赋值,参数1是哪一个对象的,参数2赋值为什么
field.set(obj, 20000);
System.out.println(obj);
field = forName.getField("hobby");
field.set(obj,"学习");
field.set(obj,"哈哈");
System.out.println(obj);
// 对所有的属性赋值
field = forName.getDeclaredField("stuno");
// 暴力反射
field.setAccessible(true);
field.set(obj, 1);
System.out.println(obj);
field = forName.getDeclaredField("name");
// 暴力反射
field.setAccessible(true);
field.set(obj, "张三");
System.out.println(obj);
}
}
21.5Constructor类
获取类对象中的构造
public class Demo05 {
public static void main(String[] args) throws Exception {
Class<?> forName = Class.forName("com.qf.test.Student");
Object object = forName.newInstance();
System.out.println(object);
// 在创建空的构造方法
Constructor<?> constructor = forName.getConstructor();
object = constructor.newInstance();
System.out.println(object);
// 有参构造
constructor = forName.getConstructor(String.class);//变长参数是声明构造中参数的类型
object = constructor.newInstance("张三");//变长参数和上面类型的个数是对应的
System.out.println(object);
// 两个参数
constructor = forName.getConstructor(int.class,String.class);
object = constructor.newInstance(10,"张三");
System.out.println(object);
// 三个参数
constructor = forName.getDeclaredConstructor(int.class,String.class,int.class);
// 暴力反射
constructor.setAccessible(true);
object = constructor.newInstance(10,"李四",20);
System.out.println(object);
}
}
21.6Method类
类对象中的方法
public class Demo06 {
public static void main(String[] args) throws Exception {
Class<?> forName = Class.forName("java.lang.String");
Constructor<?> constructor = forName.getDeclaredConstructor(String.class);
// 创建空对象
Object obj = constructor.newInstance("helloworld");
// 反向的获取一个方法,通过方法名和参数的类型
Method method = forName.getDeclaredMethod("length");
// 反向的执行
System.out.println(method.invoke(obj));
obj = constructor.newInstance("helloworld");
// 反向的获取一个方法,通过方法名和参数的类型
method = forName.getDeclaredMethod("substring",int.class,int.class);
// 反向的执行
System.out.println(method.invoke(obj,2,6));
}
}