• Java基础_类的加载机制和反射


    类的使用分为三个步骤:

      类的加载->类的连接->类的初始化

    一、类的加载  

      当程序运行的时候,系统会首先把我们要使用的Java类加载到内存中。这里加载的是编译后的.class文件

      每个类加载到内存中,会创建一个对应的Class对象。这个Class对象保存了这个类有哪些成员(数据成员,方法成员)

      注意:这里只有在某个Java类被使用的时候,才会被加载

      加载时机:任何用到这个类的时候。(实例化,使用里面的静态静态成员....)

    二、类加载器(JVM里面的一个东西)

      作用:将.class文件(可能在磁盘上,也可能在网络上)加载到内存中,并生成与之对应的java.lang.Class对象。

      分类: 

        Bootstrap ClassLoader 根类加载器  加载JRE中的核心类,比如java.lang.String 。。。

        Extension ClassLoader 扩展类加载器  加载JRE中的扩展类

        System ClassLoader 系统类加载器  一般用来加载我们自己写的类

    三、反射

      解释:在程序运行的时候,查看一个类有哪些信息(包含的数据成员和方法成员)。这个过程称之为反射。

      如果我们知道我们要使用哪个类,那么我们只需要只用这个对应的类创建对象,然后就可以调用获取这个对象里面的数据和调用里面的方法。

        (知道类,知道这个类里面有哪些属性和方法---->使用这个对象里面对应的属性和方法)

      但是我们不知道我们要使用的是哪个类,这个时候我们需要使用反射获取到类的信息,里面有哪些成员,再使用。

        (不知道---->获取类信息--->使用(实例化对象,调用属性和方法))反射

    四、获取Class对象(反射的第一步)

      方式一:通过对象获得

      方式二:通过类获得

      方式三:Class.forName("类路径")//必须传递完整路径(加上包名)

    package com.Gary2;
    
    public class User {
    
        private int id;
        private String username;
        private String password;
        
        public User() {};
        
        public User(int id,String username,String password) {
            this.id = id;
            this.username = username;
            this.password = password;
        }
        
        public void show(){
            System.out.println(username+":"+password);
        }
        
        public void study() {
            System.out.println("学习");
        }
        
        public void study(String courseName) {
            System.out.println("正在学习"+courseName);
        }
        
    }
    User.java

      方式一:通过对象获得

        Class c1 = user1.getClass();

      

      (通过User类获取到同一个User对象,一个类只能被加载一次,产生同一个User对象。)

    package com.Gary2;
    
    public class GaryGetClass {
    
        public static void main(String[] args) {
            //获取Class对象
            User user1 = new User(100,"Gary","123");
            User user2 = new User(200,"Gary2","456");
            
            //获得c1对象
            Class c1 = user1.getClass();
            System.out.println(c1);
            
            //获得c2对象
            Class c2 = user2.getClass();
            System.out.println(c2);
            
            //判断两个对象是不是一样的
            System.out.println(c1 == c2);
        }
    }
    GaryGetClass.java

      方式二:通过类

        Class c2 = user2.getClass();

      

    package com.Gary2;
    
    public class GaryGetClass {
    
        public static void main(String[] args) {
            //获取Class对象
            User user1 = new User(100,"Gary","123");
            User user2 = new User(200,"Gary2","456");
            
            //获得c1对象
            Class c1 = user1.getClass();
            System.out.println(c1);
            
            //获得c2对象
            Class c2 = user2.getClass();
            System.out.println(c2);
            
            //通过类获得User对象
            Class c4 = User.class;
            System.out.println(c4 == c1);
            
            
            
            
        }
    }
    GaryGetClass.java

       方式三:Class.forName("类路径")//必须传递完整路径(加上包名)

        Class c5 = Class.forName("com.Gary2.User");    //一定要加上包名

      

    package com.Gary2;
    
    public class GaryGetClass {
    
        public static void main(String[] args) {
            //获取Class对象
            User user1 = new User(100,"Gary","123");
            User user2 = new User(200,"Gary2","456");
            
            //获得c1对象
            Class c1 = user1.getClass();
            System.out.println(c1);
            
            //获得c2对象
            Class c2 = user2.getClass();
            System.out.println(c2);
            
            //通过类获得User对象
            Class c4 = User.class;
            
            //Class,forName
            try {
                Class c5 = Class.forName("com.Gary2.User");    //一定要加上包名
                System.out.println(c5 == c4);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            
            
            
            
        }
    }
    GaryGetClass.java

    五、利用反射构造对象

      从Class对象中获取信息

      getConstructors();//获取所有public构造方法信息
      getConstructor(Class<?> ... parameterTypes );//根据参数类型,获取指定参数类型的public构造方法
      getDeclaredConstructor(Class<?> ... parameterTypes );//忽略访问权限,获取构造方法
      getDeclaredConstructors();//忽略访问权限,获取构造方法
        getFields();//获得某个类的所有的公共(public)的字段,包括父类中的字段。 
        getDeclaredFields();//获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
        getField();//设置公共全局变量
        getDeclaredField;//仅能获取类本身的属性成员(包括私有、共有、保护) 
      getMethod();//获取当前类及所有继承的父类的public修饰的方法
      getMethods();//获取所有公有方法
      getDeclaredMethod();//该方法是获取本类以及父类或者父接口中所有的公共方法(public修饰符修饰的)
      getDeclaredMethods();//该方法是获取本类中的所有方法,包括私有的(private、protected、默认以及public)的方法。
    Constructor成员:
            newInstance();//静态方法来实例化对象以便操作
            setAccessible();//Accessable属性是继承自AccessibleObject 类. 功能是启用或禁用安全检查 ,提高java反射速度的方法method.setAccessible(true) 
  • 相关阅读:
    无序数组求第K大/第K小的数
    [洛谷][二分搜索]进击的奶牛
    [015]向下类型转换和向上类型转换
    [014]析构函数为虚函数的注意事项
    [013]函数重载--int*和void*的匹配优先级
    [012]链表笔记--在链表中插入一个节点
    [011]链表笔记--删除一个链表节点
    [002]链表笔记--编程实现一个单链表的创建/测长/打印
    [C++]对象的销毁机制
    [011]默认实参
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/11947619.html
Copyright © 2020-2023  润新知