一、class类、class对象、反射介绍
1、反射:是一种解剖class对象的技术
2、能解剖出点啥来?
a.成员变量 --> 赋值取值
b.构造方法 --> new对象
c.成员方法 --> 调用执行
3、反射的作用:写出来的代码更灵活,通用
4、反射是解剖 class 对象的,所以玩反射第一步要干嘛?
获取 class 对象
5、class对象:class文件对应的对象
class类:描述 class 对象的类叫做 class 类。
二、获取Class对象
方式1:调用Object中的getClass()方法:
Class<?> getClass()
方式2:不管是基本类型还是引用类型,jvm都为其提供了一个静态成员:class
方式3:Class类中的静态方法:
static Class<?> forName(String className)
className:类的全限定名(包名.类名)
1、创建一个Person类
public class Person {
private String name;
private Integer age;
public Person() {
}
//私有
private Person(){
System.out.println("我是私有构造");
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2、测试
public class Test01 {
public static void main(String[] args) throws Exception {
Person person = new Person();
Class aClass = person.getClass();
System.out.println("aClass = " + aClass);
System.out.println("=========");
Class personClass = Person.class;
System.out.println("personClass = " + personClass);
System.out.println("==========");
Class aClass1 = Class.forName("com.atguigu.b_reflect.Person");
System.out.println("aClass1 = " + aClass1);
}
}
结果:
aClass = class com.atguigu.b_reflect.Person
=========
personClass = class com.atguigu.b_reflect.Person
==========
aClass1 = class com.atguigu.b_reflect.Person
三、获取Class对象中的构造方法
1、获取所有public的构造方法:
Constructor<?>[] getConstructors() --> 获取的所有public的构造
2、获取空参和有参构造_(有参,无参)
Constructor<T> getConstructor(Class<?>... ParameterTypes)
-->获取指定的public的构造
parameterTypes:可变参数,可以传递0或多个参数
a.如果获取的是空参构造:参数不用写
b.如果获取的是有参构造:参数写参数类型的class对象
3、利用空参和有参构造创建对象的快捷方式_(有参,无参)
T newInstance(Object... initargs) --> 根据空参构造new对象
前提:被反射的类中必须有public的空参构造
a.如果根据空参构造new对象,initargs不写了
b.如果根据有参构造new对象,initargs传递实参
4、利用反射获取私有构造(暴力反射)
1).Constructor<?>[] getDeclaredConstructors() -> 获取所有构造方法,包括private和public
2).Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) -> 获取指定构造,包括private和public
parameterTypes:参数类型的class对象
3).Constructor有一个父类叫做AccessibleObject,里面有一个方法:
void setAccessible(boolean flag) -> 修改访问权限
flag为true-> 解除私有权限
四、反射方法
1、获取所有成员方法_public
Method[] getMethods() -> 获取所有的public的方法,包括父类中的public方法
2、获取方法(有参,无参)
Method getMethod(String name, Class<?>... parameterTypes)->获取指定的public的成员方法
name:传递方法名
parameterTypes:方法参数类型的class对象
Method中的方法:
Object invoke(Object obj, Object... args) -> 执行方法
obj:根据构造new出来的对象
args:方法实参
在web中Servlet类中反射的使用:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获得flag的参数,进行判断
request.setCharacterEncoding("utf-8");
String flag = request.getParameter("flag");
//通过反射获得想要调用的方法对象
Class c = this.getClass();//c就是子类的类信息
try {
Method method = c.getDeclaredMethod(flag, HttpServletRequest.class, HttpServletResponse.class);
//调用这个函数
method.setAccessible(true);//暴力访问
method.invoke(this,request,response);
} catch (Exception e) {
e.printStackTrace();
}
}