高级Java作业2

文章展示了如何使用Java反射技术从Person.class生成.java源代码,创建PersonProxy代理类在setter方法调用时记录时间和方法信息到文本文件。同时,通过动态代理技术实现了相同的功能,利用Proxy.newProxyInstance方法创建代理实例,代理setter方法并在调用时写入日志。
摘要由CSDN通过智能技术生成

第2次作业:反射与动态代理

1.编写一个Person类,生成class文件,请通过反射技术,为Person.class生成新的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。

2.请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:

时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平

3.请用动态代理技术完成第2题(答辩时要求结合Proxy.newProxyInstance的内部源码解释其实现过程)

 

package lib.Work2.Reflection01;

/**
 * 1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
 * 2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
 * 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
 * 3、(3分)请用动态代理技术完成第2题
 */
public class Person implements Speakable {
    private String name;//学生姓名
    private String Gender;//性别
    private String id;//身份证号
    private String tel;//电话

    public Person() {
    }

    public Person(String name, String Gender, String id, String tel) {
        this.name = name;
        this.Gender = Gender;
        this.id = id;
        this.tel = tel;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return Gender;
    }

    public void setGender(String Gender) {
        this.Gender = Gender;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    @Override
    public String toString() {
        return "PersonRefection{" +
                "name='" + name + '\'' +
                ", sex='" + Gender + '\'' +
                ", id='" + id + '\'' +
                ", tel='" + tel + '\'' +
                '}';
    }

    @Override
    public void speak(String message) {
        System.out.println(message);
    }
}
package lib.Work2.Reflection01;
//1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
//2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
//        时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
//3、(3分)请用动态代理技术完成第2题


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.*;

public class PersonReflection {
    static String pathName = "D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Reflection01\\Person.java";
    static FileOutputStream fos;

    static {
        try {
            fos = new FileOutputStream(pathName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    static Class clazz;

    static {
        try {
            clazz = Class.forName("Person");
            fos = new FileOutputStream(pathName);
        } catch (ClassNotFoundException | FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void getPackage(String pathName) {
        String packageName = clazz.getPackage().getName();
        String writePackage = "package " + packageName + ";\n\n";
        try {
            fos.write(writePackage.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(final String[] args) throws NoSuchMethodException, IOException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {

        FileOutputStream fos = new FileOutputStream(pathName);
        Class clazz = Class.forName("Person");
        //获取类所在的包名
        String packageName = clazz.getPackage().getName();
        String writePackage = "package " + packageName + ";\n\n";
        fos.write(writePackage.getBytes());

        //获取类中的权限修饰符及类名并输出
        String modifier = Modifier.toString(clazz.getModifiers());
        String className = clazz.getSimpleName();
        String writeClass = modifier + " class " + className + " {\n";
        fos.write(writeClass.getBytes());

        //获取类中所有的字段
        Field[] fieldArray = clazz.getDeclaredFields();
        for (Field f : fieldArray) {
            String mod = Modifier.toString(f.getModifiers());
            String type = f.getType().getSimpleName();
            String name = f.getName();
            String writeField = "\t" + mod + " " + type + " " + name + ";\n";
            fos.write(writeField.getBytes());
        }
        fos.write("\n".getBytes());

        //获取类中所有的构造方法
        Constructor[] constructorArray = clazz.getConstructors();
        for (Constructor c : constructorArray) {
            String mod = Modifier.toString(c.getModifiers());
            String writeConstructor = "\t" + mod + " " + className + "(";

            //获取构造方法里面所有的参数
            Class[] prams = c.getParameterTypes();
            int count = 0;
            for (Class cl : prams) {
                String pramName = cl.getSimpleName();
                writeConstructor += pramName + " args" + count;
                if (count < prams.length - 1) {
                    writeConstructor += ", ";
                }
                count++;
            }
            writeConstructor += ") {}\n";
            fos.write(writeConstructor.getBytes());
        }
        fos.write("\n".getBytes());

        //获取类中所有的方法
        Method[] methodArray = clazz.getDeclaredMethods();
        for (Method m : methodArray) {
            String mod = Modifier.toString(m.getModifiers());
            String type = m.getReturnType().getSimpleName();
            String name = m.getName();
            String writeMethod = "\t" + mod + " " + type + " " + name + "(";

            //与构造方法一样,获取方法里面所有的参数
            Class[] prams = m.getParameterTypes();
            int count = 0;
            for (Class cl : prams) {
                String pramName = cl.getSimpleName();
                writeMethod += pramName + " args" + count;
                if (count < prams.length - 1) {
                    writeMethod += ", ";
                }
                count++;
            }
            writeMethod += ") {\n";

            if (type.equals("int") || type.equals("double")) {
                writeMethod += "\t\treturn 0;\n";
            } else if (type.equals("boolean")) {
                writeMethod += "\t\treturn false;\n";
            } else if (type.equals("void")) {
                writeMethod += "";
            } else {
                writeMethod += "\t\treturn null;\n";
            }
            writeMethod += "\t}\n\n";
            fos.write(writeMethod.getBytes());
        }
        fos.write("}".getBytes());
    }
}
 
package lib.Work2.Reflection01;

import java.io.IOException;

public interface Speakable {
    void speak(String message);

    void setName(String args0) throws IOException;

    void setTel(String args0) throws IOException;

    void setGender(String args0) throws IOException;

    void setId(String args0) throws IOException;
}

package lib.Work2.Proxy02;

/**
 * 1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
 * 2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
 * 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
 * 3、(3分)请用动态代理技术完成第2题
 */
public class Person implements Speakable {
    private String name;//学生姓名
    private String Gender;//性别
    private String id;//身份证号
    private String tel;//电话

    public Person() {
    }

    public Person(String name, String Gender, String id, String tel) {
        this.name = name;
        this.Gender = Gender;
        this.id = id;
        this.tel = tel;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return Gender;
    }

    public void setGender(String Gender) {
        this.Gender = Gender;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    @Override
    public String toString() {
        return "PersonRefection{" +
                "name='" + name + '\'' +
                ", sex='" + Gender + '\'' +
                ", id='" + id + '\'' +
                ", tel='" + tel + '\'' +
                '}';
    }

    @Override
    public void speak(String message) {
        System.out.println(message);
    }
}
package lib.Work2.Proxy02;

import lib.Work2.Reflection01.Person;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;

//2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
//        时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
public class PersonProxy implements Speakable {
    Person person;
    File file = new File("D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Proxy02\\PersonProxy.text");

    public PersonProxy(Person person) {
        this.person = person;
    }

    @Override
    public void speak(String message) {

    }

    public void setName(String name) throws IOException {
        WriteToText(file, "setName", name);
        this.person.setName(name);
    }


    public void setGender(String Gender) throws IOException {
        WriteToText(file, "setGender", Gender);
        this.person.setGender(Gender);
    }


    public void setId(String id) throws IOException {
        WriteToText(file, "setId", id);
        this.person.setId(id);
    }


    public void setTel(String tel) throws IOException {
        WriteToText(file, "setTel", tel);
        this.person.setTel(tel);
    }

    public void WriteToText(File file, String MethodName, String parameter) throws IOException {

        //如果文件不存在,就动态创建文件
        if (!file.exists()) {
            file.createNewFile();
        }
        final String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
        try (FileWriter fw = new FileWriter(file, true)) {
            //设置为:True,表示写入的时候追加数据
            //回车并换行
            fw.write(writeDate + "\r\n");
        } catch (final IOException e) {
            e.printStackTrace();
        }

    }

    private String get_nowDate() {
        Calendar D = Calendar.getInstance();
        int year = 0;
        int moth = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        year = D.get(Calendar.YEAR);
        moth = D.get(Calendar.MONTH) + 1;
        day = D.get(Calendar.DAY_OF_MONTH);
        hour = D.get(Calendar.HOUR_OF_DAY);
        minute = D.get(Calendar.MINUTE);
        second = D.get(Calendar.SECOND);
        return year + "-" + moth
                + "-" + day + " " + hour + ":"
                + minute + ":" + second;

    }

}
package lib.Work2.Proxy02;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

class PersonRefection {
    static String pathName = "D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Proxy02\\Person.java";
    static FileOutputStream fos;

    static {
        try {
            fos = new FileOutputStream(pathName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException, ClassNotFoundException {
        getPackage();
        getClazz();
        getField();
        getConstructor();
        getMethod();

    }

    /**
     * 获取包名
     */
    public static void getPackage() throws ClassNotFoundException {
        Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
        String packageName = clazz.getPackage().getName();
        String writePackage = "package " + packageName + ";\n\n";
        try {
            fos.write(writePackage.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取类中的权限修饰符及类名并输出
     */
    public static void getClazz() throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
        String modifier = Modifier.toString(clazz.getModifiers());
        String className = clazz.getSimpleName();
        String writeClass = modifier + " class " + className + " {\n";
        fos.write(writeClass.getBytes());
    }

    /**
     * 获取类中所有的字段
     */
    public static void getField() throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
        Field[] fieldArray = clazz.getDeclaredFields();
        for (Field f : fieldArray) {
            String mod = Modifier.toString(f.getModifiers());
            String type = f.getType().getSimpleName();
            String name = f.getName();
            String writeField = "\t" + mod + " " + type + " " + name + ";\n";
            fos.write(writeField.getBytes());
        }
        fos.write("\n".getBytes());
    }

    /**
     * 获取类中所有的构造方法
     */
    public static void getConstructor() throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
        String className = clazz.getSimpleName();
        Constructor[] constructorArray = clazz.getConstructors();
        for (Constructor c : constructorArray) {
            String mod = Modifier.toString(c.getModifiers());
            String writeConstructor = "\t" + mod + " " + className + "(";

            //获取构造方法里面所有的参数
            Class[] prams = c.getParameterTypes();
            int count = 0;
            for (Class cl : prams) {
                String pramName = cl.getSimpleName();
                writeConstructor += pramName + " args" + count;
                if (count < prams.length - 1) {
                    writeConstructor += ", ";
                }
                count++;
            }
            writeConstructor += ") {}\n";
            fos.write(writeConstructor.getBytes());
        }
        fos.write("\n".getBytes());

    }

    /**
     * 获取类中所有的方法
     */
    public static void getMethod() throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
        Method[] methodArray = clazz.getDeclaredMethods();
        for (Method m : methodArray) {
            String mod = Modifier.toString(m.getModifiers());
            String type = m.getReturnType().getSimpleName();
            String name = m.getName();
            String writeMethod = "\t" + mod + " " + type + " " + name + "(";

            //与构造方法一样,获取方法里面所有的参数
            Class[] prams = m.getParameterTypes();
            int count = 0;
            for (Class cl : prams) {
                String pramName = cl.getSimpleName();
                writeMethod += pramName + " args" + count;
                if (count < prams.length - 1) {
                    writeMethod += ", ";
                }
                count++;
            }
            writeMethod += ") {\n";

            switch (type) {
                case "int", "double" -> writeMethod += "\t\treturn 0;\n";
                case "boolean" -> writeMethod += "\t\treturn false;\n";
                case "void" -> writeMethod += "";
                default -> writeMethod += "\t\treturn null;\n";
            }
            writeMethod += "\t}\n\n";
            fos.write(writeMethod.getBytes());
        }
        fos.write("}".getBytes());
    }


}
package lib.Work2.Proxy02;

import java.io.IOException;

public interface Speakable {
    void speak(String message);

    void setName(String args0) throws IOException;

    void setTel(String args0) throws IOException;

    void setGender(String args0) throws IOException;

    void setId(String args0) throws IOException;
}

package lib.Work2.DynamicProxy03;


import java.io.IOException;
import java.lang.reflect.Proxy;

public class BootStrap {
    public static void main(final String[] args) throws IOException {
        //创建一个真实对象
        Person person = new Person();
        //创建一个动态代理对象
        MyProxy myProxy = new MyProxy(person);
        //获取被代理类的CLassLoader对象
        ClassLoader loader = person.getClass().getClassLoader();
        //动态构造一个代理对象
        Speakable speakable = (Speakable) Proxy.newProxyInstance(loader,
                new Class[]{Speakable.class},//接口对象数组,表示我们要给代理对象提供一个怎样的接口,如果提供了这样一组接口数组,就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。
                myProxy);
        speakable.setGender("man");


    }
}
package lib.Work2.DynamicProxy03;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar;

public class MyProxy implements InvocationHandler {
    File file = new File("D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\DynamicProxy03\\DynamicProxy.text");
    private final Object proxied;

    public MyProxy(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //proxy:代理类代理的真实代理对象
        //method:我们要调用某个对象真实的方法的Method对象
        //args:代理对象方法传递的参数
        WriteToText(file, method.getName(), (String) args[0]);
        method.invoke(this.proxied, args);
        return null;
    }

    public void WriteToText(File file, String MethodName, String parameter) throws IOException {

        //如果文件不存在,就动态创建文件
        if (!file.exists()) {
            file.createNewFile();
        }
        String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
        try (FileWriter fw = new FileWriter(file, true)) {
            //设置为:True,表示写入的时候追加数据
            //回车并换行
            fw.write(writeDate + "\r\n");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String get_nowDate() {
        Calendar D = Calendar.getInstance();
        int year = 0;
        int moth = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        year = D.get(Calendar.YEAR);
        moth = D.get(Calendar.MONTH) + 1;
        day = D.get(Calendar.DAY_OF_MONTH);
        hour = D.get(Calendar.HOUR_OF_DAY);
        minute = D.get(Calendar.MINUTE);
        second = D.get(Calendar.SECOND);
        return year + "-" + moth
                + "-" + day + " " + hour + ":"
                + minute + ":" + second;

    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package lib.Work2.DynamicProxy03;

public class Person implements Speakable {
    private String name;
    private String Gender;
    private String id;
    private String tel;

    public Person() {
    }

    public Person(String name, String Gender, String id, String tel) {
        this.name = name;
        this.Gender = Gender;
        this.id = id;
        this.tel = tel;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return this.Gender;
    }

    public void setGender(String Gender) {
        this.Gender = Gender;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTel() {
        return this.tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String toString() {
        return "PersonRefection{name='" + this.name + "', sex='" + this.Gender + "', id='" + this.id + "', tel='" + this.tel + "'}";
    }

    public void speak(String message) {
        System.out.println(message);
    }
}
package lib.Work2.DynamicProxy03;

import java.io.IOException;

public interface Speakable {
    void speak(String message);

    void setName(String args0) throws IOException;

    void setTel(String args0) throws IOException;

    void setGender(String args0) throws IOException;

    void setId(String args0) throws IOException;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值