Java学习笔记(反射+枚举类)

19 反射

19.1 类的加载概述和加载时机

19.1.1 类的加载概述

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

  • 加载:
    指将class文件读入内存中,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象。
  • 连接:
    • 验证:是否有正确的内部结构,并和其他类协调一致
    • 准备:负责为类的静态成员分配内存,并设置默认初始化值
    • 解析:将类的二进制数据中的符号引用替换为直接引用
  • 初始化:即初始化步骤。
19.1.2 加载时机
  • 创建类的实例
  • 访问类的静态变量,或者为静态变量赋值
  • 调用类的静态方法
  • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
  • 初始化某个类的子类
  • 直接使用java.exe命令来运行某个主类。

19.2 类加载器的概述和分类

19.2.1 类加载器的概述
  • 负责将.class文件加载到内存中,并为之生成对应的Class对象。虽然我们并不关心类加载机制,但是了解这个机制可以更好理解程序运行。
19.2.2 类加载器的分类
  • Bootstrap ClassLoader 根类加载器
  • Extension ClassLoader 扩展类加载器
  • System ClassLoader 系统类加载器
19.2.3 类加载器的作用
  • Bootstrap ClassLoader 根类加载器
    • 也称为引导类加载器,负责Java核心类的加载
    • 比如System,String等,在JDK中JRE的lib目录下rt.jar文件中
  • Extension ClassLoader 扩展类加载器
    • 负责JRE的扩展目录中jar包的加载
    • 在JDK中JRE的lib目录下ext目录
  • System ClassLoader 系统类加载器
    • 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径

19.3 反射概述

  • 概述
    • JAVA反射机制是运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
    • 对于任意一个对象,都能够调用他的任意一个方法和属性;
    • 这种动态获取的信息以及动态调用的方法的功能称为java语言的反射机制;
    • 想要解剖一个类,必须先要获取到该类的字节码文件对象;
    • 而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应Class类型的对象。
      这里写图片描述

例1:获取字节码文件对象的三种方式

Person.java

        package com.mirror.gf;

        public class Person {
            private String name;
            private int age;
            public Person(){
                super();
            }
            public Person(String name,int age){
                super();
                this.name = name;
                this.age = age;
            }

            public boolean equals(Object obj) {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                if (getClass() != obj.getClass())
                    return false;
                Person other = (Person) obj;
                if (age != other.age)
                    return false;
                if (name == null) {
                    if (other.name != null)
                        return false;
                } else if (!name.equals(other.name))
                    return false;
                return true;
            }                      
        }

Demo_Reflect.java

package com.mirror.gf;

public class Demo_Reflect {
    public static void main(String[] args) throws ClassNotFoundException{
    Class clazz1 = Class.forName("com.mirror.gf.Person");
    Class clazz2 = Person.class;
    Person p = new Person();
    Class clazz3 = p.getClass();

    System.out.println(clazz1== clazz2);
    System.out.println(clazz2== clazz3);
    }
}

运行结果:

ture
ture

例2:Class.forName()读取配置文件举例

Demo2_Reflect.java

package com.mirror.gf;

import java.io.BufferedReader;
import java.io.FileReader;

public class Demo2_Reflect {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        //使用反射与配置文件
        BufferedReader br = new BufferedReader(new FileReader("config.properties"));
        Class clazz = Class.forName(br.readLine());
        Fruit f = (Fruit) clazz.newInstance();

        Eat eat = new Eat();
        eat.run(f); 

        br.close(); 
        //未用反射
        /*Eat eat = new Eat();
        eat.run(new Orange());*/
    }
}
interface Fruit{
    public void eat();
}

class Apple implements Fruit{
    public void eat(){
    System.out.println("吃苹果");
    }
}

class Orange implements Fruit{
    public void eat(){
    System.out.println("吃橙子");
    }
}

class Eat{
    public void run(Fruit f){
        f.eat();
    }
}

配置文件congfig.properties&#x

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值