目录
一.反射概念
class:指的是普通的类,代表汉子"类".
Class:指的是类类型,就是普通类的类型,即 class 的类型.
class(普通类)本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建唯一的Class实例。
Class实例包含该class的所有信息,通过Class实例获取class信息的方法称为反射(Reflection)
二.类对象概念和获取方式
1.类对象概念:
所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
类对象,就是用于描述这种类,都有什么属性,什么方法的
2.获取类对象方式
获取类对象有3种方式
1. Class.forName
2. Hero.class
3. new Hero().getClass()
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。
try {
Class clazz1=Class.forName("com.main.java.Student1");
Class clazz2= Student1.class;
Class clazz3=new Student1().getClass();
//单例的
System.out.println(clazz1==clazz2);
System.out.println(clazz1==clazz3);
}catch (Exception e){
e.printStackTrace();
}
三.获取类的信息和类的类型
从Class实例获取class信息:
getName() //包名+类名
getSimpleName() //只是类名
getPackage() //只是包名,注:前面会有 package
从Class实例判断class类型:
isInterface() //是否是接口
isEnum() //是否是枚举
isArray() //是否是数组
isPrimitive() // 确定指定的Class对象表示一个基本类型。有九种预定义的Class对象代表的八个基本类型和void。这些都是由Java虚拟机创建的,并且具有相同的名称,它们代表即boolean, char,byte, short, int, long, float, 和double 等原始类型
public static void main(String[] args){
System.out.println(" main 线程开始执行...");
try {
Class clazz= Student1.class;
Class clazz1=boolean.class;
System.out.println(clazz.getName()); //com.main.java.Student1
System.out.println(clazz.getSimpleName()); //Student1
System.out.println(clazz.getPackage()); //package com.main.java
System.out.println(clazz.isInterface()); //false
System.out.println(clazz.isEnum()); //false
System.out.println(clazz.isArray()); //false
System.out.println(clazz.isPrimitive()); //false
System.out.println(clazz1.isPrimitive()); //true
}catch (Exception e){
e.printStackTrace();
}
}
四.获取继承关系
1.获取直接父类的类对象(Class)
Class getSuperclass() Object的父类是null, interface的父类是null
2.获取当前类直接实现的interface
Class[] getInterfaces() 不包括间接实现的interface 没有interface的class返回空数组 interface返回继承的interface
五.获取构造方法信息 并创建对象
1.获取构造器对象
通过Class实例获取Constructor信息(构造器对象):
getConstructors() 返回所有 public 的构造器对象。
getDeclaredConstructors() 返回所有 public和非 public,private的构造器对象。
getConstructor(Class<?>... parameterTypes) 返回制定参数类型而且访问权限是public的构造器对象。
getDeclaredConstructor(Class<?>... parameterTypes) 返回制定参数类型的所有构造器对象,包括public的和非public的,当然也包括private的。
Class clazz= Student1.class;
//获取构造器对象
Constructor[] constructors =clazz.getConstructors();
Constructor cc=clazz.getConstructor(String.class,int.class);
Student1 stu=(Student1)cc.newInstance("joe",22);
System.out.println(stu.getName());
2.通过构造器对象创建实例对象
newInstance(Object… parameters)
通过设置setAccessible(true)来访问非public构造方法。
//获取构造器对象
Constructor[] constructors =clazz.getConstructors();
Constructor cc=clazz.getConstructor(String.class,int.class);
cc.setAccessible(true);
Student1 stu=(Student1)cc.newInstance("joe",22);
System.out.println(stu.getName());
六.获取字段信息 获取和设置字段的值
1.通过类对象(Class)获取字段对象
getField(name):获取某个public的field(包括父类)
getDeclaredField(name):获取当前类的某个field(不包括父类)
getFields():获取所有public的field(包括父类)
getDeclaredFields():获取当前类的所有field(不包括父类)
2.Field对象包含一个field的所有信息
getName() //获取字段名称
getType() //获取字段类型
getModifiers() //获取字段修饰符
3.获取和设置field的值
get(Object obj)
set(Object, Object) 通过设置setAccessible(true)来访问非public字段。
Class clazz= Student1.class;
Student1 stu=(Student1)clazz.newInstance();
//获取字段对象
Field field=clazz.getDeclaredField("no");
System.out.println(field.getName());
System.out.println(field.getType());
System.out.println(field.getModifiers());
field.setAccessible(true);
field.set(stu,3);//设置字段值
System.out.println(field.get(stu));
七.获取方法信息 访问和调用方法
1.通过Class实例获取方法对象(Method)
getMethod(String name, Class<?>... parameterTypes):获取某个public的method(包括父类)
getDeclaredMethod(String name, Class<?>... parameterTypes):获取当前类的某个method(不包括父类)
getMethods():获取所有public的method(包括父类)
getDeclaredMethods():获取当前类的所有method(不包括父类)
2.Method对象包含一个method的所有信息
getName() //获取方法名
getReturnType() //获取方法返回类型
getParameterTypes() //获取方法参数类型
getModifiers() //获取方法修饰符
3.调用方法
Object invoke(Object obj, Object... args) 通过设置setAccessible(true)来访问非public方法。
Class clazz= Student1.class;
Student1 stu=(Student1)clazz.newInstance();
//获取字段
Method setMethod=clazz.getDeclaredMethod("setNo",int.class);
setMethod.setAccessible(true);
setMethod.invoke(stu,33);
System.out.println(stu.getNo());