【Java高级程序设计】类型信息与反射实验

目录

第一题

第二题:

第三题: 


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题

 第一题

请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。

Speakable接口:

import java.io.IOException;

public interface Speakable {
    public void speak(String message);

    public void setName(String args0) throws IOException;

    public void setTel(String args0) throws IOException;

    public void setGender(String args0) throws IOException;

    public void setId(String args0) throws IOException;
}

 Person类:

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);
    }
}

 用反射技术,为附件中的Person.class生成相应的.java代码:


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

public class PersonRefection {
    static String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\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 {

        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        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());
    }
}

第二题:

请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为: * 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平

Person类:

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

	public Person() {}
	public Person(String args0, String args1, String args2, String args3) {}

	public String toString() {
		return null;
	}

	public String getName() {
		return null;
	}

	public void setName(String args0) {
	}

	public String getId() {
		return null;
	}

	public void setGender(String args0) {
	}

	public String getTel() {
		return null;
	}

	public void speak(String args0) {
	}

	public void setTel(String args0) {
	}

	public String getGender() {
		return null;
	}

	public void setId(String args0) {
	}

}

 代理类:


import homework2.experiment1.Person;
import homework2.experiment1.Speakable;

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("E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Log");

    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();
        }
        FileWriter fw = null;
        final String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
        try {
            //设置为:True,表示写入的时候追加数据
            fw = new FileWriter(file, true);
            //回车并换行
            fw.write(writeDate + "\r\n");
        } catch (final IOException e) {
            e.printStackTrace();
        } finally {
            if (fw != null) {
                fw.close();
            }
        }

    }

    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);
        String now_date = String.valueOf(year) + "-" + String.valueOf(moth)
                + "-" + String.valueOf(day) + " " + String.valueOf(hour) + ":"
                + String.valueOf(minute) + ":" + String.valueOf(second);
        return now_date;

    }

}

 


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;

public class PersonRefection {
    static String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\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, FileNotFoundException {
        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        Class<?> clazz = Class.forName("homework2.experiment2.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 {
        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        Class<?> clazz = Class.forName("homework2.experiment2.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 {
        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        Class<?> clazz = Class.forName("homework2.experiment2.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 {
        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        Class<?> clazz = Class.forName("homework2.experiment2.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 {
        String pathName = "E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment2\\Person.java";
        Class<?> clazz = Class.forName("homework2.experiment2.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":
                case "double":
                    writeMethod += "\t\treturn 0;\n";
                    break;
                case "boolean":
                    writeMethod += "\t\treturn false;\n";
                    break;
                case "void":
                    writeMethod += "";
                    break;
                default:
                    writeMethod += "\t\treturn null;\n";
                    break;
            }
            writeMethod += "\t}\n\n";
            fos.write(writeMethod.getBytes());
        }
        fos.write("}".getBytes());
    }


}

实现类:

import java.io.IOException;

public class Bootstrap {
    public static void main(final String[] args) throws IOException {
        Person person = new Person();
        PersonProxy personProxy = new PersonProxy(person);
        personProxy.setId("123");
        personProxy.setName("xxx");
    }
}

生成日志如图:

第三题: 

 请用动态代理技术完成第2题

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("E:\\学习\\代码\\AdvancedJAVA\\src\\homework2\\experiment3\\Log");
    private 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();
        }
        FileWriter fw = null;
        String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
        try {
            //设置为:True,表示写入的时候追加数据
            fw = new FileWriter(file, true);
            //回车并换行
            fw.write(writeDate + "\r\n");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fw != null) {
                fw.close();
            }
        }

    }

    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);
        String now_date = String.valueOf(year) + "-" + String.valueOf(moth)
                + "-" + String.valueOf(day) + " " + String.valueOf(hour) + ":"
                + String.valueOf(minute) + ":" + String.valueOf(second);
        return now_date;

    }
}

实现类:


import homework2.experiment1.Speakable;

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");


    }
}

日志生成如图:

 

Class类简介

从某种意义上来讲,java有两种对象:实例对象Class对象

每个类的运行时的类型信息就是用Class对象表示的。它包含了与类有关的信息。实际上实例对象就是通过Class对象来创建的。Java使用Class对象执行其RTTI(运行时类型识别),多态就是基于RTTI实现的

每个类都有一个Class对象,每编译一个新类就会产生一个Class对象,基本类型、数组、关键字void等都有Class对象。Class对象对应着java.lang.Class类,如过说类是对象抽象和集合的话,那么Class类就是对类的抽象和集合。

Class类没有公共的构造方法,Class对象是在类加载的时候由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的,因此不能显示的声明一个Class对象。一个类被加载到内存并供我们使用需要经历如下三个阶段:

1.加载,这是由类加载器(ClassLoader)执行的。通过一个类的全限定名来获取其定义的二进制字节流(Class字节码),将这个字节流所代表的静态存储结构转化为方法去的运行时数据接口,根据字节码在java堆中生成一个代表这个类的java.lang.Class对象。

2.链接。在链接阶段将验证Class文件中的字节流包含的信息是否符合当前虚拟机的要求,为静态域分配存储空间并设置类变量的初始值(默认的零值),并且如果必需的话,将常量池中的符号引用转化为直接引用。

3.初始化。到了此阶段,才真正开始执行类中定义的java程序代码。用于执行该类的静态初始器和静态初始块,如果该类有父类的话,则优先对其父类进行初始化。

所有的类都是在对其第一次使用时,动态加载到JVM中的(懒加载)。当程序创建第一个对类的静态成员的引用时,就会加载这个类。使用new创建类对象的时候也会被当作对类的静态成员的引用。因此java程序程序在它开始运行之前并非被完全加载,其各个类都是在必需时才加载的。这一点与许多传统语言都不同。动态加载使能的行为,在诸如C++这样的静态加载语言中是很难或者根本不可能复制的。

在类加载阶段,类加载器首先检查这个类的Class对象是否已经被加载。如果尚未加载,默认的类加载器就会根据类的全限定名查找.class文件。在这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良java代码。一旦某个类的Class对象被载入内存,我们就可以它来创建这个类的所有对象。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天的命名词

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值