动态代理
接口:
public interface Star {
public String sing(String name);
public void dance();
}
实现类:
public class BigStar implements Star{
private String name;
public BigStar() {
}
public BigStar(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+"正在跳舞");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "daili.BigStar{" +
"name='" + name + '\'' +
'}';
}
}
代理类:
public class ProxyUtil {
public static Star createProxy(BigStar bigStar) {
//代理类的类加载器、Class数组、InvocationHandler对象(实现invoke方法)
Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler() {
//InvocationHandler接口必须实现invoke方法,参数为目标类对象、目标类方法、目标类方法参数数组
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("sing".equals(method.getName())) {
System.out.println("准备话筒,收钱");
} else if ("dance".equals(method.getName())) {
System.out.println("准备场地,收钱");
}
method.invoke(bigStar, args);
return "谢谢";
}
}
);
return star;
};
}
测试类:
public class Test {
public static void main(String[] args) {
BigStar bigStar = new BigStar("鸡哥");//创建目标对象
Star proxy = ProxyUtil.createProxy(bigStar);//创建代理对象
String result = proxy.sing("只因你太美");
System.out.println(result);
proxy.dance();
}
}
反射
获取类的class对象,描述字节码文件的,用io流不能区分方法,变量和构造器;
结合配置文件动态创建对象。
获取类的class方法的三种方式
源代码阶段
Class clazz = Class.forName("fanshe.Student");
加载阶段
Class clazz2 = Student.class;
运行阶段
Class clazz3 = new Student().getClass();
反射获取类的构造方法
实体类
public class Student {
private String name;
private int age;
public Character gender;
public Student(String name) {
this.name = name;
}
Student(int age) {
this.age = age;
}
private Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
public static void main(String[] args) throws Exception {
//获取class字节码文件对象
Class clazz = Class.forName("fanshe.Student");
Constructor constructor1 = clazz.getConstructor(String.class);
int modifiers1 = constructor1.getModifiers();
System.out.println("public:1 :0 protected:4 private:2");
System.out.println("获取权限修饰符:"+modifiers1);
System.out.println(constructor1);
System.out.println("===============================================");
Constructor declaredConstructor1 = clazz.getDeclaredConstructor(int.class);
Constructor declaredConstructor2 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(declaredConstructor1+"\n"+declaredConstructor2);
System.out.println("获取构造方法参数:" +
"\n"+declaredConstructor2.getParameters()[0]+
"\n"+declaredConstructor2.getParameters()[1]);
declaredConstructor2.setAccessible(true);
System.out.println(declaredConstructor2.newInstance("张三",23));
System.out.println("===============================================");
//获取所有public修饰的构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("===============================================");
//获取所有构造方法
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
}
反射获取成员变量
测试类
public static void main(String[] args) throws Exception {
//获取class字节码文件对象
Class clazz = Class.forName("fanshe.Student");
System.out.println(clazz);
//获取所有成员变量(包括非public修饰的)
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("===============================");
Field gender = clazz.getDeclaredField("gender");
System.out.println(gender+",修改符:"+gender.getModifiers()+
"\n"+"名称:"+gender.getName()+
"\n"+"类型:"+gender.getType());
//获取对象的私有成员变量的值
Field name = clazz.getDeclaredField("name");
Student student = new Student("张三");
name.setAccessible(true);
Object o = name.get(student);
System.out.println(o);
}
反射获取成员方法及方法参数
测试类
public static void main(String[] args) throws Exception {
//获取class字节码文件对象
Class clazz = Class.forName("fanshe.Student");
//获取本类中所有public方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("====================================");
//不能获取父类,但是可以获取本类中非public的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("====================================");
Method setAge = clazz.getMethod("setAge", int.class);//有重载
System.out.println(setAge+",修饰符:"+setAge.getModifiers());
System.out.println("方法的参数:");
Class[] parameterTypes = setAge.getParameterTypes();
for (Class parameterType : parameterTypes) {
System.out.println(parameterType);
}
System.out.println("====================================");
System.out.println("方法抛出的异常:");
Class[] exceptionTypes = setAge.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {
System.out.println(exceptionType);
}
System.out.println("=======================");
Student student = new Student("李四");
Method setName = clazz.getMethod("setName", String.class);
setName.invoke(student,"王五");
System.out.println(student);
}
反射结合IO流写出类信息
测试类
Student student = new Student("李四");
student.setAge(23);
student.gender='男';
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("C:\\Users\\25130\\Desktop\\t3.txt"));
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
bufferedOutputStream.write((declaredField.getName()+":"+
declaredField.get(student)+"\n").getBytes());
}
bufferedOutputStream.close();
反射读配置文件,动态创建对象和运行方法
public static void main(String[] args) {
try (FileInputStream fileInputStream = new FileInputStream("prop.properties");) {
Properties properties = new Properties();//HashTable的子类
properties.load(fileInputStream);//添加流
System.out.println(properties);//{classname=fanshe.Student, method=setName}
String classname = (String) properties.get("classname");
String method = (String) properties.get("method");
System.out.println(classname + "====" + method);
Class clazz = Class.forName(classname);//fanshe.Student
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor);
Student student = (Student) declaredConstructor.newInstance("王五");
System.out.println(student);//Student{name='王五', age=0}
Method declaredMethod = clazz.getDeclaredMethod(method, String.class);
declaredMethod.invoke(student, "张三");
System.out.println(student);//Student{name='张三', age=0}
} catch (Exception e) {
throw new RuntimeException(e);
}
}