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) 

 

 

 

posted @ 2019-11-28 11:11  Cynical丶Gary  阅读(128)  评论(0编辑  收藏  举报