zoukankan      html  css  js  c++  java
  • 类加载、反射

    类的加载

    当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载连接初始化三步来实现对这个类进行初始化。

    加载

    就是指将class文件读入内存,并为之创建一个Class对象。

    任何类被使用时系统都会建立一个Class对象

    连接

    验证 是否有正确的内部结构,并和其他类协调一致

    准备 负责为类的静态成员分配内存,并设置默认初始化值

    解析 将类的二进制数据中的符号引用替换为直接引用

    初始化

    初始化阶段,虚拟机负责对类的变量进行初始化

    • 声明类变量是指定初始值
    • 使用静态初始化块为类变量指定初始值

     Class类的初始化时机

    Java虚拟机只有在程序首次主动使用一个类或接口的时候才会初始化它。只有6种活动被看作是程序对类和接口的主动使用

    1. 创建类的实例
    2. 调用类的静态方法
    3. 访问类或接口的静态变量,或者为静态变量赋值
    4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
    5. 初始化某个类的子类
    6. 直接使用java.exe命令来运行某个主类

    反射

    JAVA反射机制是在运行状态中:

    对于任意一个,都能够知道这个类的所有属性和方法

    对于任意一个对象,都能够调用它的任意一个方法和属性

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。

    类也是一种类型

    获取Class对象三种方式

    方式一:调用Object类的getClass():任何类都会继承此方法

    Person p = new Person();

    Class c = p.getClass()

    方式二:调用某个类的class属性来获取该类对应Class对象

    Class s = Student.class

    方式三:调用Class类的静态方法forName(String clazzName),参数的值是某个类的全限定类名(必须添加完整包名)

    Class c3 = Class.forName("类的全限定类名");

    目的:通过这个Class对象,可以获取Student类内部的成员属性、构造方法、成员方法的一些信息,并能够调用它们

    学生类

    class Student {
        // 成员变量
        public String name;
        public int age;
        private String address;
    
        // 构造方法
        public Student() {
            System.out.println("空参数构造方法");
        }
    
        public Student(String name) {
            this.name = name;
            System.out.println("带有String的构造方法");
        }
    
        // 私有的构造方法
        private Student(String name, int age) {
            this.name = name;
            this.age = age;
            System.out.println("私有-------带有String,int的构造方法");
        }
    
        public Student(String name, int age, String address) {
            this.name = name;
            this.age = age;
            this.address = address;
            System.out.println("带有String, int, String的构造方法");
        }
    
        // 成员方法
        // 没有返回值没有参数的方法
        public void m1() {
            System.out.println("没有返回值没有参数的方法");
        }
    
        // 没有返回值,有参数的方法
        public void m2(String name) {
            System.out.println("没有返回值,有参数的方法 name= " + name);
        }
    
        // 有返回值,没有参数
        public int m3() {
            System.out.println("有返回值,没有参数的方法");
            return 123;
        }
    
        // 有返回值,有参数的方法
        public String m4(String name) {
            System.out.println("有返回值,有参数的方法");
            return "哈哈" + name;
        }
    
        // 私有方法
        private void m5() {
            System.out.println("私有方法");
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
        }
    }
    学生类

    通过反射获取构造方法

    在反射机制中,把类中的成员(构造方法、成员方法、成员变量)都封装成了对应的类进行表示。其中,构造方法使用类Constructor表示。可通过Class类中提供的方法获取构造方法:

    获取单个

    Constructor getConstructor(Class ... parameterTypes):获取指定的"公有构造方法"

    Constructor getDeclaredConstructor(Class ... parameterTypes):获取指定的构造方法(包括私有的)

    批量获取构造方法

    Constructor[] getConstructors() :获取所有的"公有构造方法"

    Constructor[] getDeclaredConstructors() :获取全部(包括私有)的构造方法

    暴力访问:如果想要访问私有成员,需要设置暴力访问

    ConstructorsetAccessible(true):不进行权限检查

     通过反射方式创建对象(有构造)

    步骤如下:

    1. 获取到Class对象

    2. 获取指定的构造方法

    3. 通过构造方法类Constructor中的方法,创建对象

    public class Demo {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
                InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            // 1. 获取到Class对象
            Class clazz = Class.forName("Student的全限定名");// 包名.类名
            // 2. 获取指定的构造方法
            Constructor c1 = clazz.getConstructor();
    
            // 相当于调用无参构造方法创建对象,返回Object类型的对象
            Object o1 = c1.newInstance();
        System.out.println("------------------------------------------");
            
            // 获取三个参数的构造方法
            Constructor c2 = clazz.getConstructor(String.class, int.class, String.class);
            // 调用三个参数的构造方法
            Object obj = c2.newInstance("小红", 22, "南京");
            // Student [name=小红, age=22, address=南京]
            System.out.println(obj);
        }
    View Code

    在反射机制中,把类中的成员方法使用类Method表示。可通过Class类中提供的方法获取成员

    l 获取多个

    Method[] getMethods():获取所有"公有方法"(包括继承的)

    Method[] getDeclaredMethods() :获取所有成员方法(包括私有)

    l 获取单个成员方法

    Method getMethod(String name, Class... parameterTypes) :获取指定的"公有方法"

    Method getDeclaredMethod(String name, Class... parameterTypes) :获取指定的方法,包括私有的

    调用方法:(注意:1.要先创建此类的对象;2.调用私有方法前,要先设置暴力访问)

    Method

    Object invoke(Object obj, Object... args) :调用Method所代表的方法

    返回值:此Method对象调用所代表的方法,所获取的返回值;

    形参:

    obj:方法所属对象;

    args:Method所代表的那个方法的实参列表

  • 相关阅读:
    Linux入门之常用命令(12) mount
    Linux入门之运维(1) 系统监控 vmstat top
    【转】常用Maven插件
    【转】Mapreduce部署与第三方依赖包管理
    ssh (免密码登录、开启服务)
    增大hadoop client内存
    ubuntu12.04添加程序启动器到Dash Home
    jquery fadeOut 异步
    jquery 全选 全不选 反选
    js 上传文件预览
  • 原文地址:https://www.cnblogs.com/cmm123/p/13214778.html
Copyright © 2011-2022 走看看