1:反射(理解)
(1)类的加载及类加载器
(2)反射:
通过字节码文件对象,去使用成员变量,构造方法,成员方法
(3)反射的使用
A:通过反射获取构造方法并使用
package com.itheima.test;
public class Person {
private String name;
int age;
public String address;
public Person() {
}
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void show() {
System.out.println("show");
}
public void method(String s) {
System.out.println("method " + s);
}
public String getString(String s, int i) {
return s + "---" + i;
}
private void function() {
System.out.println("function");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address
+ "]";
}
}
主类:
//获取公共构造方法
Class c=Class.forName("com.itheima.test.Person");
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
输出结果:
public com.itheima.test.Person(java.lang.String,int,java.lang.String)
public com.itheima.test.Person()
主类:
//获取所有构造方法
Class c=Class.forName("com.itheima.test.Person");
Constructor[] declaredConstructors = c.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor);
}
输出结果:
private com.itheima.test.Person(java.lang.String)
com.itheima.test.Person(java.lang.String,int)
public com.itheima.test.Person(java.lang.String,int,java.lang.String)
public com.itheima.test.Person()
主类:
Class c=Class.forName("com.itheima.test.Person");
//获取无参构造函数
Constructor con=c.getConstructor();
System.out.println(con);
//获取有参构造函数对象
Constructor con1=c.getConstructor(String.class, int.class, String.class);
Object instance = con1.newInstance("fan",15,"1234");
System.out.println(con1);
System.out.println(instance);
//获取有参构造函数对象
Constructor con2=c.getConstructor(String.class,int.class);
Object instance2 = con2.newInstance("fab1",15);
System.out.println(con2);
System.out.println(instance2);
输出结果:
public com.itheima.test.Person()
public com.itheima.test.Person(java.lang.String,int,java.lang.String)
Person [name=fan, age=15, address=1234]
public com.itheima.test.Person(java.lang.String,int)
Person [name=fab1, age=15, address=null]
主类:
Class c = Class.forName("com.itheima.test.Person");
// 获取私有构造方法对象
// NoSuchMethodException:每个这个方法异常
// 原因是一开始我们使用的方法只能获取公共的,下面这种方式就可以了。
Constructor con = c.getDeclaredConstructor(String.class);
System.out.println(con);
// 用该私有构造方法创建对象
// IllegalAccessException:非法的访问异常。
// 暴力访问
con.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。
Object obj = con.newInstance("风清扬");
System.out.println(obj);
输出结果 :
private com.itheima.test.Person(java.lang.String)
Person [name=风清扬, age=0, address=null]
B:通过反射获取成员变量并使用
Class c = Class.forName("com.itheima.test.Person");
//获取所有的公共成员变量
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("---------------");
//获取所有的成员变量
Field[] fields2 = c.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
System.out.println("---------------");
//获取单个的成员变量
// 通过无参构造方法创建对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
System.out.println(obj);
Field field = c.getField("address");
field.set(obj,"fas");
System.out.println(obj);
输出结果:
public java.lang.String com.itheima.test.Person.address
---------------
private java.lang.String com.itheima.test.Person.name
int com.itheima.test.Person.age
public java.lang.String com.itheima.test.Person.address
---------------
Person [name=null, age=0, address=null]
Person [name=null, age=0, address=fas]
C:通过反射获取成员方法并使用
主类:
Class c = Class.forName("com.itheima.test.Person");
//获取自己和父亲方法的公共方法
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("----------");
//获取自己的所有的方法
Method[] methods2 = c.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
System.out.println("----------");
//获取单个的方法
Constructor con = c.getConstructor();
Object obj = con.newInstance();
Method m2 = c.getMethod("method", String.class);
m2.invoke(obj, "hello");
System.out.println("----------");
输出结果:
public java.lang.String com.itheima.test.Person.toString()
public java.lang.String com.itheima.test.Person.getString(java.lang.String,int)
public void com.itheima.test.Person.method(java.lang.String)
public void com.itheima.test.Person.show()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public boolean java.lang.Object.equals(java.lang.Object)
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
----------
public java.lang.String com.itheima.test.Person.toString()
public java.lang.String com.itheima.test.Person.getString(java.lang.String,int)
public void com.itheima.test.Person.method(java.lang.String)
public void com.itheima.test.Person.show()
private void com.itheima.test.Person.function()
----------
method hello
----------
(4)反射案例
A:通过反射运行配置文件的内容
Class c4 = Class.forName("cn.itcast_01.Person");
System.out.println(c == c4);
B:通过反射越过泛型检查
ArrayList<String> arrayList=new ArrayList<String>();//指定泛型为Integer
Class c=arrayList.getClass();//获取Class文件对象
Method addMethod=c.getDeclaredMethod("add",Object.class);//获取Class文件对象中的add()方法
Student s=new Student("fan",20);
addMethod.invoke(arrayList, "asdfg");//越过泛型检查,添加String类型
addMethod.invoke(arrayList, s);//越过泛型检查,添加Student类型
System.out.println(arrayList);//结果为:[asdfg, Student [name=fan, age=20]]
C:通过反射给任意的一个对象的任意的属性赋值为指定的值
(5)动态代理
StudentDao类
public interface StudentDao {
public abstract void login();
public abstract void regist();
}
StudentImpl类
public class StudentDaoImpl implements StudentDao {
@Override
public void login() {
System.out.println("登录功能");
}
@Override
public void regist() {
System.out.println("注册功能");
}
}
//代理对象类 MyInvocationHandler
public class MyInvocationHandler implements InvocationHandler {
private Object target; // 目标对象
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("权限校验");
Object result = method.invoke(target, args);
System.out.println("日志记录");
return result; // 返回的是代理对象
}
}
主类:
StudentDao sd = new StudentDaoImpl();
MyInvocationHandler handler2 = new MyInvocationHandler(sd);
StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler2);
proxy2.login();
proxy2.regist();