您的位置:首页 > 编程语言 > Java开发

java基础19(Javaoo14)——反射、类加载与垃圾回收

2016-12-11 18:55 369 查看
反射(Reflect)是Java的灵魂,体会反射的意义和威力!

Class forName("类名");//加载类
字符串拼接很重要
1.反射是什么?
Java反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法,这种动态获取的以及动态调用对象的方法的功能称之为java语言的反射机制.
2.反射做什么?
3.反射与动态多态的关系?
上述都是做Javaweb和javaEE的基础

                                          Map(映射)

studentBean(Object)                                  (Relationship)   t_student
         属性                                                                 字段 

类加载:类的Class文件读入内存后,会创建一个java.lang.Class 类模版对象:专门装载类的信息,只有注释没有被加载,一旦某个类载入JVM中,同一个类不会再次被载入.

实例对象:我们new出来的,可以有无数个(比如实例出来的Student对象)
类模版对象:装我们书写的类,只会加载一次(比如我们自己写的Student类的信息)
反射机制的 API——本来是JVM使用
但是当程序员使用反射机制的 API——运行时探究和使用编译时未知的类(例子:联想   .方法)

String str = new String("Hello!")
这里面产生了几个对象?
3个,一个是装载String类的类模版对象,一个在字符串常量池,一个是我们new出来的.
静态代码块只在类加载期间只执行一次!

内存:栈区(局部变量),堆区(new 出来的),数据段静态区(字符串常量池),代码区(方法)

反射使用步骤:
1.获取你想操作的类的Java.lang.calss 对象 (获取)
2.调用诸如 getDeclaredMethods 的方法(探究)
3.使用(使用)

1.反射第一步:获取Class对象
2.探究
探究声明
探究属性用——Field     
探究属性Field的4个方法:所有公共的,所有声明的,指定公共的,指定声明的(后面2个传参传属性名)
探究构造Constructor的4个方法:所有公共的,所有声明的,指定公共的,指定声明的(后面2个传参,传参数列表)
探究方法Method的4个方法:所有公共的,所有声明的,指定公共的,指定声明的(后面2个传参,传参数列表)
当数组做形参时可以用数组类型...数组名的语法糖方式

public static void main(String[] args) {
        // TODO Auto-generated method stub
    //1、反射第一步:获取Class对象
        //1-1、调用实例对象继承于Object的getClass方法
        /*特点
         * 1、可以得到所有类和数组的Class对象
         * 2、没有编译时未知,运行时探究的动态效果
         */
        DogBean snoopy = new DogBean();
        Class dogClass = snoopy.getClass();//得到DogBean的Class对象
        Class strClass = "hello".getClass();
        Class dateClass = new Date().getClass();
        int[] arrayInt = new int[5];
        Class intArrayClass = arrayInt.getClass();
        DogBean[] allDogs = new DogBean[5];
        Class allDogsClass = allDogs.getClass();
        
        //1-2、利用语法:类型名.class的方式获取到Class对象
        /*特点:
         * 1、所有类型(不管是基本数据类型还是引用数据类型,甚至是返回类型void)都可以得到相应的Class对象
         * 2、没有编译时未知,运行时探究的动态效果
         */
        Class dogClass1 = DogBean.class;
//        System.out.println(dogClass == dogClass1);//证明一个类只会有一个Class对象
        Class strClass1 = String.class;
        Class dateClass1 = Date.class;
        Class intArrayClass1 = int[].class;
        Class allDogsClass1 = DogBean[].class;
        Class intClass = int.class;//可以得到int的Class对象--基本数据类型.class只能在JDK1.5以后使用
        Class integerClass = Integer.class;
        Class intClass1 = Integer.TYPE;//JDK1.5之前获取基本数据类型的Class对象
        Class voidClass = void.class;
        
        //1-3、利用Class.forName("字符串形式的类型名")获取Class对象
        /*特点:
         * 1、不支持基本数据类型、返回类型和数组获取相应Class对象
         * 2、拥有编译时未知,运行时探究的动态效果
         */
        try {
            Class dogClass2 = Class.forName("com.lovo.bean.DogBean");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    //2、探究类的信息
        //2-0、探究类的基本声明部分
        String packageName = dogClass.getPackage().getName();//探究包名
        System.out.println("package " + packageName + ";");
        String className = dogClass.getName();//探究类全名、类的限定名
        String classSimpleName = dogClass.getSimpleName();//探究类的简写名
        int intMod = dogClass.getModifiers();//得到修饰符--访问修饰符和可选修饰符的组合
        String classModStr = Modifier.toString(intMod);//使用工具类把整型的修饰符表示转换为字符串的修饰符表示
        String superClassName = dogClass.getSuperclass().getName();//得到父类
        Class[] allInterClasses = dogClass.getInterfaces();//得到接口
        String interStr = "";
        if(allInterClasses != null && allInterClasses.length != 0){
            interStr = "implements ";
            for(int i = 0; i < allInterClasses.length; i++){
                interStr += allInterClasses[i].getSimpleName();
                if(i != allInterClasses.length - 1){
                    interStr += ",";
                }else{
                    interStr += " ";
                }
            }
        }
        
        
        System.out.println(classModStr + " class " + classSimpleName + 
                " extends "+superClassName + " " + interStr +  
                "{");
        //2-1、探究属性--Field
        System.out.println("===============属性==============");
        Field[] allPublicFields = dogClass.getFields();//得到所有的公共属性(包括父类继承而来的公共属性)
        Field[] allFields = dogClass.getDeclaredFields();//得到所有申明的属性(不包括来自父类的)
        try {
            Field thePublicField = dogClass.getField("name");//得到指定的公共属性(包括父类继承而来的);
            Field theField = dogClass.getDeclaredField("age");//得到指定的申明属性(不包括来自父类的)
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        for(Field f : allFields){
            String fName = f.getName();//属性名
            String fType = f.getType().getSimpleName();//属性类型
            String fMod = Modifier.toString(f.getModifiers());//属性修饰符
            System.out.println("\t" + fMod + " " + fType + " " + fName + ";");
            
        }
        //2-2、探究构造---Constructor
        System.out.println("===============构造==============");
        Constructor[] allPublicCons = dogClass.getConstructors();//得到所有公共的构造方法
        Constructor[] allDeclaredCons = dogClass.getDeclaredConstructors();//得到所有申明的构造
        try {
            Constructor thePublicCon = dogClass.getConstructor();//得到指定公共构造
            Constructor theCon = dogClass.getDeclaredConstructor(String.class,int.class,boolean.class);//得到指定申明构造
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        for(Constructor con : allDeclaredCons){
            String cMod = Modifier.toString(con.getModifiers());//构造方法修饰符
            String cName = con.getName();//构造方法名--真正的构造方法名就是类全名
            String paramStr = "";//参数列表
            String exceptionStr = "";//抛出的异常
            
            Class[] paramsClass = con.getParameterTypes();//得到形参列表
            if(paramsClass != null && paramsClass.length != 0 ){
                for(int i = 0; i < paramsClass.length; i++){
                    paramStr  += paramsClass[i].getSimpleName();
                    if(i != paramsClass.length - 1){
                        paramStr += ",";
                    }
                }
            }
            
            Class[] exeTypes = con.getExceptionTypes();
            if(exeTypes != null && exeTypes.length != 0){
                exceptionStr = "throws ";
                for(int i = 0; i < exeTypes.length; i++){
                    exceptionStr += exeTypes[i].getSimpleName();
                    if(i != exeTypes.length - 1){
                        exceptionStr += ",";
                    }
                }
            }
            System.out.println("\t" + cMod + " " + cName + " (" + paramStr + ") " + exceptionStr + "{}");
        }
        
        //2-3、探究方法---Method
        System.out.println("===============方法==============");
        Method[] allPublicMethods = dogClass.getMethods();
        Method[] allDeclaredMethods = dogClass.getDeclaredMethods();
        try {
            Method thePublicMethod = dogClass.getMethod("bark");
            Method theMethod = dogClass.getDeclaredMethod("bark", int.class);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for(Method method : allDeclaredMethods){
            String cMod = Modifier.toString(method.getModifiers());//方法修饰符
            Class cReturn = method.getReturnType();//得到返回类型class对象
            String cReturnName = cReturn.getSimpleName();//返回对象返回String字符串
            String cName = method.getName();//方法名--真正的方法名就是类全名
            String paramStr = "";//参数列表
            String exceptionStr = "";//抛出的异常
            
            Class[] paramsClass = method.getParameterTypes();//得到形参列表
            if(paramsClass != null && paramsClass.length != 0 ){
                for(int i = 0; i < paramsClass.length; i++){
                    paramStr  += paramsClass[i].getSimpleName();
                    if(i != paramsClass.length - 1){
                        paramStr += ",";
                    }
                }
            }
            
            Class[] exeTypes = method.getExceptionTypes();
            if(exeTypes != null && exeTypes.length != 0){
                exceptionStr = "throws ";
                for(int i = 0; i < exeTypes.length; i++){
                    exceptionStr += exeTypes[i].getSimpleName();
                    if(i != exeTypes.length - 1){
                        exceptionStr += ",";
                    }
                }
            }
            System.out.println("\t" + cMod + " " + cReturnName +" "+ cName + " (" + paramStr + ") " + exceptionStr + "{}");
        }
        
        System.out.println("}");
        
    //3、使用探究到的类的信息
        //3-1、使用反射创建对象----Java中第三种创建对象的方法---newInstance()
        //3-1-1、根据探究到的Constructor对象,产生类的实例对象
        /*
         * 好处:可以调用类中任意构造方法
         * 坏处:实现过于麻烦
         */
        try {
            DogBean dog = null;
            Constructor theCon = dogClass.getDeclaredConstructor(String.class,int.class,boolean.class,String.class);
//            Constructor theCon = dogClass.getDeclaredConstructor();
            theCon.setAccessible(true);//设置theCon的访问权限为可访---不到万不得已不准用
            dog = (DogBean)theCon.newInstance("旺财",5,true,"周周");//这个方法在反射中用来产生实例对象的
            System.out.println(dog.getName());
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //3-1-2、直接利用Class对象产生实例对象
        /*
         * 好处:代码简洁
         * 坏处:只能调用公共无参构造 
         */
        try {
            DogBean dog = null;
            dog = (DogBean) dogClass.newInstance();
            System.out.println(dog);
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //3-2、操作属性---get/set
        try {
            DogBean dog0 = new DogBean();
            DogBean dog1 = new DogBean();
            dog0.name = "大黄";
            
            Field theField = dogClass.getDeclaredField("name");
            theField.setAccessible(true);//不准用
            theField.set(dog1, "小白");//给Field对象赋值,第一个参是代表给哪个狗对象的name属性赋值
            System.out.println(theField.get(dog0));//给Field对象取值
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //3-3、调用探究到的方法---invoke()
        
        try {
            Method thePublicMethod = dogClass.getDeclaredMethod("bark",int.class);
            thePublicMethod.setAccessible(true);//不准用
            thePublicMethod.invoke(snoopy,10);
            
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: