动态代理
依次创建
package com.liu.learn;
public class BigStar implements Star{
private String name;
public BigStar() {
}
public BigStar(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String sing(String name) {
System.out.println(this.name+"正在唱"+name);
return "谢谢";
}
@Override
public void dance() {
System.out.println(this.name+"正在跳舞");
}
}
package com.liu.learn;
public interface Star {
//唱歌
public abstract String sing(String name);
//跳舞
public abstract void dance();
}
package com.liu.learn;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
*
*类的作用:
* 创建一个代理
*/
public class ProxyUtil {
/**
* 方法的作用:
* 给一个明星的对象,创建一个代理
* 形参
* 被代理的明星对象
* 返回值
* 给明星创建的代理
*
* @param bigStar
* @return
*/
public static Star createProxy(BigStar bigStar){
Star star=(Star) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类
new Class[]{Star.class}, //参数二:指定接口,这些接口用于指定生成的代理有哪些方法
new InvocationHandler() { //参数三:用来指定生成的代理对象要干什么事情
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 参数一:代理的对象
* 参数二:要运行的方法 sing
* 参数三:调用sing的时候,传递的实参
*/
if("sing".equals(method.getName())){
System.out.println("准备话筒,收钱");
}else if("dance".equals(method.getName())){
System.out.println("准备场地,收钱");
}
return method.invoke(bigStar,args);
}
}
);
return star;
}
}
package com.liu.learn;
public class Test {
public static void main(String[] args) {
//1 获取代理的对象
BigStar bigStar=new BigStar("张学友");
Star proxy = ProxyUtil.createProxy(bigStar);
//2
String s = proxy.sing("月亮代表我的心");
System.out.println(s);
proxy.dance();
}
}
运行结果为:
准备话筒,收钱
张学友正在唱月亮代表我的心
谢谢
准备场地,收钱
张学友正在跳舞
反射概念
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
获取class对象的三种方式
public static void main(String[] args) throws ClassNotFoundException {
/**
* 获取对象的三种方法
* 1.Class.forName("全类名")
* 2.类名.class
* 3.对象.getClass
*/
//1 第一种方法
//全类名: 包名 + 类名
//最为常用的
Class cls = Class.forName("com.liu.myReflect1.Student");
System.out.println(cls);
//第二种方式
//一般更多的是当作参数传递
// synchronized (Student.class){
//
// }
Class<Student> cls2 = Student.class;
System.out.println(cls2);
//第三种方式
//当我们已经有了这个对象时,才可以使用
Student student=new Student();
Class<? extends Student> cls3 = student.getClass();
System.out.println(cls3);
}
利用反射获取构造方法
//1. 获取class字节码文件对象
Class cls = Class.forName("com.liu.myReflect2.Student");
//2. 获取构造方法
/*
Constructor[] constructors = cls.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor[] declaredConstructors = cls.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor);
}
Constructor constructor = cls.getDeclaredConstructor();
System.out.println(constructor);
Constructor constructor1 = cls.getDeclaredConstructor(String.class);
System.out.println(constructor1);
Constructor constructor2 = cls.getDeclaredConstructor(int.class);
System.out.println(constructor2);
*/
Constructor constructor3 = cls.getDeclaredConstructor(String.class,int.class);
System.out.println(constructor3);
// 获取修饰符
// int i = constructor3.getModifiers();
// System.out.println(i);
// //获取形参
// int count = constructor3.getParameterCount();
// System.out.println(count);
//暴力反射:临时取消权限检验
constructor3.setAccessible(true);
//创建对象
Student stu = (Student) constructor3.newInstance("张三", 23);
System.out.println(stu);
利用反射获取成员变量
//1.获取class字节码文件的对象
Class cls = Class.forName("com.liu.myReflect3.Student");
//2. 获取所有的成员变量
// Field[] fields = cls.getDeclaredFields();
// for (Field field : fields) {
// System.out.println(field);
// }
// 获取单个的成员变量
Field gender = cls.getDeclaredField("gender");
System.out.println(gender);
//获取成员变量的权限修饰符
int modifiers = gender.getModifiers();
System.out.println(modifiers);
//获取成员变量的名字
String name = gender.getName();
System.out.println(name);
//获取成员变量的数据类型
Class<?> type = gender.getType();
System.out.println(type);
//获取成员变量记录的值
Student stu=new Student("张三",23,"男");
gender.setAccessible(true);
Object o = gender.get(stu);
System.out.println(o);
//修改对象里面记录的值
gender.set(stu,"女");
System.out.println(stu);
利用反射获取成员方法
反射的作用
- 获取一个类里面所有的信息,获取到了以后,再执行其他的业务逻辑
- 结合配置文件,动态的创建对象并调用方法
package com.liu.myReflect5;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.lang.reflect.Field;
public class MyReflectDemo {
public static void main(String[] args) throws Exception{
Student s=new Student("小A",24,'男',179.5,"睡觉");
Teacher t=new Teacher("波妞",10000);
saveObject(s);
}
public static void saveObject(Object o) throws Exception {
//1 获取字节码文件
Class cls = o.getClass();
//2 创建IO流
BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\IdeaProjects\\myReflect\\a.txt"));
//3 获取所有的成员变量
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
Object value = field.get(o);
bw.write(name+"="+value);
bw.newLine();
}
bw.close();
}
}
Properties prop=new Properties();
FileInputStream fis=new FileInputStream("D:\\IdeaProjects\\myReflect\\prop.properties");
prop.load(fis);
fis.close();
System.out.println(prop);
String className=(String) prop.get("classname");
String methodName = (String) prop.get("method");
System.out.println(className+methodName);
Class cls = Class.forName(className);
Constructor con = cls.getDeclaredConstructor();
Object o = con.newInstance();
Method method = cls.getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(o);