Java底层-JVM

Java的理解

  • 平台无关性
  • GC 垃圾回收机制
  • 语言特性:反射、范型、lambda表达式等
  • 面向对象:多态、继承、封装
  • 类库:集合、并发库、IO库等
  • 异常处理

平台无关性

Jvm可以从软件层屏蔽不同的操作系统在底层硬件与指令上的区别。

.java文件通过javac编译生成.class文件,.class文件中包含:编译生成的二进制码、java类中的属性、方法和静态属性。可以通过java自带的javap命令反编译查看.class文件,了解java编译器内部机制。

  • javap指令(javap -help查看), -c 对代码进行反汇编。
    在这里插入图片描述

JVM架构

Java虚拟机JVM,抽象化的、运行在内存中的虚拟化计算机,通过模拟仿真各种计算机功能。JVM屏蔽了与具体操作系统平台相关的信息,使得java编译后可以在各种平台运行。

在这里插入图片描述

Class Loader(类装载系统):依据特定格式,加载class文件到Runtime Data Area。

Execution Engine(字节码执行引擎):对命令进行解析。

Native Interface(本地方法接口):融合不同开发语言的原生库为java所用。

Runtime Data Area(运行时数据区):JVM内存空间结构模型。

JVM如何加载class文件?

Java反射机制

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有方法和属性;对于任意一个对象都能够调用任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

定义反射类Robot,包括私有属性name、公共方法sayHi、私有方法throwHello。

package com.Interview.javabasic;

public class Robot {
   
    private   String name;
    public void sayHi(String helloSentence){
   
        System.out.println(helloSentence + "" +name);
    }
    private String throwHello(String tag){
   
        return "hello" + tag;
    }
}

定义反射实例类,通过forName获取反射类、newInstance实例化反射类、getDeclaredMethod和getMethod获取反射类的方法、getDeclaredField获取反射类的属性、invoke调用反射类的方法并且可以传入参数。

package com.Interview.javabasic;

import javax.swing.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectSample {
   
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
   
        //forName根据类的路径获取类对象
        Class rc = Class.forName("com.Interview.javabasic.Robot");
        //通过newInstance获取类的实例,因为newInstance返回的实例类型是范性,需要强转。
        Robot  r = (Robot) rc.newInstance();
        System.out.println("class name "+rc.getName());
        //getDeclaredMethod能够获取反射类的所有包括公共和私有方法,但是不能获取继承的方法和实现接口的方法。
        Method getHello = rc.getDeclaredMethod("throwHello",String.class);
        //getMethod只能获取公共public方法,但是可以获取反射类继承的方法和实现接口的方法。
        Method sayHi = rc.getMethod("sayHi", String.class);
        Field name = rc.getDeclaredField("name");

        //反射类的throwHello为私有方法、name为私有属性,因此需要设置setAccessible为true
        getHello.setAccessible(true);
        name.setAccessible(true);
        //给name赋值,需要传入实例化的反射类对象
        name.set(r,"alice");

        //使用Object接受返回的值,invoke()返回的是Object对象,
        Object str = getHello.invoke(r,"Bob");
        sayHi.invoke(r,"welcome");

        System.out.println("getHello result" + str);
    }

}

类从编译到执行的过程

反射获取类的class对象,必须先获取该类的字节码文件对象。

  • 编译器将Robot.java源文件编译为Robot.class字节码文件。
  • ClassLoader将字节码(byte数组格式)转换为JVM中的Class对象。
  • JVM利用Class对象实例化为Robot对象。

ClassLoader简介

ClassLoader在Java中有着非常重要的作用,它主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流。他是Java的核心组件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载近系统,然后交给Java虚拟机进行连接、初始化等操作。

ClassLoader的种类
  • BootStrapClassLoader:C++编写,加载核心库java.*,由JVM实现。
  • ExtClassLoader:Java编写,加载扩展库javax.*,可以将自定义的class进行加载。
  • AppClassLoader:Java编写,加载程序所在目录。用于加载ClassPath路径下的内容 ,例如上述的Robot.class和ReflectSample.class文件。
  • 自定义ClassLoader:Java编写,定制化加载。

findClass()根据名称和路径加载.class字节码,然后它会调用defineClass()解析定义clss字节流并返回class对象。

自定义ClassLoader实例

在这里插入图片描述

目的:自定义一个类加载器,实现加载自定义claa文件的功能。

流程:

  • 1.在工程以外创建一个Wail类(Wail.java),使用javac编译为Wail.class文件。

    public class Wail{
         
    	static{
         
    		System.out.println("Hello wail");
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的胖虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值