《反射、类加载与垃圾回收》

  1. 反射代表java动态性,java在运行期可以探索和使用编译期未知的东西,包括类属性方法接口等。
  2. 通过反射而产生对象。

类的加载机制

  1. 类加载:由类加载器完成,类的class文件读入内存后,就会创建一个java.lang.Class对象,一旦某个类被加载入JVM中,同一个类就不会再次被载入,
  2. 连接:把类的二进制数据合并到JRE中。
  3. 初始化:JVM负责对类进行初始化,也就是对静态属性进行初始化。在java类中,

反射

(1:获取class对象){掌握class.forName();}

//1-1、根据实例对象获取Class对象 //实现方法:调用实例对象的getClass(),该方法来自Object类 //适用范围:引用数据类型 //动态性:无 Student stu = new Student(); Class stuClass0 = stu.getClass(); Class strClass0 = "hello".getClass(); int[] intArray = new int[6]; Class arrayClass0 = intArray.getClass();

    //1-2、根据类型名获取Class对象
    //实现方法:调用类型名.class
    //适用范围:所有的类型(基本、引用、甚至包括void)
    //动态性:无
    Class stuClass1 = Student.class;
    Class strClass1 = String.class;
    Class arrayClass1 = int[].class;
    Class integerClass = Integer.class;//获取包装类Integer的Class对象
    Class intClass1 = Integer.TYPE;//获取int的Class对象,该方式在JDK1.5之前
    Class intClass = int.class;//获取int的Class对象,该方式在JDK1.5以后才有
    Class voidClass = void.class;
    System.out.println(stuClass0 == stuClass1);//不管用哪种方式获取,一个类型只有一个Class对象

    //1-3、根据类型的字符串名称获取Class对象
    //实现方式:调用Class.forName("类的限定名")
    //适用范围:只有类类型(包括接口)
    //动态性:有
    Class stuClass2 = null;
    try {
        stuClass2 = Class.forName("com.lovo.bean.Student");
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
(2:通过class对象探究一个类的信息){探究属性:(fiekd属性)4个;探究构造:(construction构造)4个;探究方法:(method方法)4个}
  • 2、获取Class对象中的信息 */ //2-1、探究一个类的申明部分信息 String packageName = stuClass2.getPackage().getName();//得到包名 System.out.println("package " + packageName + ";"); String className = stuClass2.getName();//得到全类名 className = stuClass2.getSimpleName();//得到简单类名 int classMod = stuClass2.getModifiers();//得到修饰符,返回的数字 String classModStr = Modifier.toString(classMod);//利用工具方法,将整型修饰符转换成字符串 Class superStuClass = stuClass2.getSuperclass();//得到父类的Class对象 String superClassName = superStuClass.getName(); Class[] interClasses = stuClass2.getInterfaces();//得到本类实现接口的Class对象(可以有多个,所以是数组) String allInter = ""; for(int i = 0; i < interClasses.length; i++){ allInter += interClasses[i].getName(); if(i < interClasses.length - 1){ allInter += ","; } } //打印类的申明部分 System.out.println(classModStr + " class " + className + " extends " + superClassName + " implements " + allInter + "{");

    //2-2、探究属性
    System.out.println("//属性");
    Field[] allPublicFields = stuClass2.getFields();//得到所有的公共属性
    Field[] allFields = stuClass2.getDeclaredFields();//得到所有被申明的属性
    try {
        Field thePublicField = stuClass2.getField("score");//得到指定的某个公共属性
        Field theField = stuClass2.getDeclaredField("name");//得到指定的某个被申明的属性
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //打印属性
    for(Field field : allFields){
        String fieldName = field.getName();//得到属性名
        Class fieldType = field.getType();//得到属性类型
        String fieldTypeName = fieldType.getName();
        int fieldMod = field.getModifiers();//得到属性对应的修饰符
        String fieldModStr = Modifier.toString(fieldMod);
        System.out.println("\t" + fieldModStr + " " + fieldTypeName + " " + fieldName);
    }
    
    //2-3、探究构造
    System.out.println("//构造方法");
    Constructor[] allPublicCons = stuClass2.getConstructors();//得到所有的公共构造
    Constructor[] allCons = stuClass2.getDeclaredConstructors();//得到所有被申明的构造
    
    try {
        //得到指定的某个公共构造方法
        Constructor thePublicCon = stuClass2.getConstructor(String.class,int.class,boolean.class);
        //得到指定的某个被申明的构造方法
        Constructor theCon = stuClass2.getDeclaredConstructor();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    //打印构造
    for(Constructor con : allCons){
        String conName = con.getName();//得到构造方法的名字
        Class[] paramClasses = con.getParameterTypes();//得到构造方法的参数列表            
        String params = "";
        if(paramClasses != null && paramClasses.length > 0){
            for(int i = 0; i < paramClasses.length; i++){
                params += paramClasses[i].getName();
                if(i < paramClasses.length - 1){
                    params += ",";
                }
            }
        }
        int conMod = con.getModifiers();//得到构造方法的修饰符
        String conModStr = Modifier.toString(conMod);
    
        System.out.println("\t" + conModStr + " " + conName + "(" + params + ")");
    }
    
    //2-4、探究方法
    System.out.println("//普通方法");
    Method[] allPublicMethods = stuClass2.getMethods();//得到所有的公共方法
    Method[] allMethods = stuClass2.getDeclaredMethods();//得到所有的申明方法
    
    try {
        Method thePublicMethod = stuClass2.getMethod("test1");//得到指定的公共方法
        //得到指定的申明方法
        Method theMethod = stuClass2.getDeclaredMethod("test2", int.class,String.class);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    //打印方法
    for(Method m : allMethods){
        String methodName = m.getName();//得到方法名
        String returnTypeStr = m.getReturnType().getName();//得到返回类型的名字
        String methodModStr = Modifier.toString(m.getModifiers());//得到方法的修饰符
        String params = "";
        Class[] paramsClasses = m.getParameterTypes();//得到方法的参数列表
        if(paramsClasses != null && paramsClasses.length > 0){
            for(int i = 0; i < paramsClasses.length; i++){
                params += paramsClasses[i].getName();
                if(i < paramsClasses.length - 1){
                    params += ",";
                }
            }
        }
        Class[] allExcs = m.getExceptionTypes();//得到方法抛出的所有异常
        String throwsStr = " ";
        if(allExcs != null && allExcs.length > 0){
            throwsStr = " throws ";
            for(int i = 0; i < allExcs.length; i++){
                throwsStr += allExcs[i].getName();
                if(i < allExcs.length - 1){
                    throwsStr += ",";
                }
            }
        }
        System.out.println("\t" + methodModStr + " " + returnTypeStr + " " + methodName + 
                "(" + params + ")" + throwsStr);
    }
    System.out.println("}");
    
(3:操作从class对象中探究出来的信息){构造:产生对象;属性:赋值、取值;方法:调用;}
        3、根据反射探究到的信息进行操作
     */
        //3-1、根据Constructor对象,产生实例对象
       //实现一:调用Constructor对象的newInstance方法
    try {
        //得到指定的某个公共构造方法
        Constructor thePublicCon = stuClass2.getConstructor(String.class,int.class,boolean.class);
        Student student = (Student)thePublicCon.newInstance("zhang3",18,true);
        System.out.println(student);
    } 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();
    }
    //实现二:直接调用Class对象的newInstance方法--前提是只能调用到公共无参构造
    try {
        Student stu0 = (Student)stuClass2.newInstance();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //3-2、根据Field对象,对属性进行取值和赋值
    //实现:调用Field的get/set方法
    try {
        Field thePublicField = stuClass2.getField("score");
        thePublicField.set(stu, 96);//赋值(注意第一个参数,代表给哪个Student对象的这个属性赋值)
        System.out.println(thePublicField.get(stu));//取值(参数代表了从哪个Student对象的这个属性取值)
    } 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、根据method对象,对方法进行调用
    //实现:调用Method对象的invoke方法
    try {
        Method thePublicMethod = stuClass2.getMethod("test3",int.class);//得到指定的公共方法
        thePublicMethod.invoke(stu,4);
    } 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();
    }
}

  1. java的反射技术是java程序的特征之一,它允许运行中的java程序对自身进行检查,或自审,并能直接操作程序内部属性。
  2. 使用发射可以获得java类类中各个成员的名称并显示出来,反射就是让你可以通过名称来得到对象(类、属性、方法)的技术
  3. 运行时探究和使用编译时未知的类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值