当前位置: 移动技术网 > IT编程>开发语言>Java > 荐 Java Virtual Machine-First part(●----●)

荐 Java Virtual Machine-First part(●----●)

2020年07月17日  | 移动技术网IT编程  | 我要评论

对Java的理解

Note : 如果源码中出现有native非访问控制修饰符时,那么说明其调用了非java实现的代码库,此时可以通过该网站进行查阅,由于oracle的jdk是部分闭源的,而openjdk是开源的,所以选择在openjdk看native lib

Overview

Extension

  • 平台无关性:编译一次,到处运行
  • GC ( Garbege Collection ):
  • 语言特性:lambda表达式,反射,泛型:
  • 面向对象:封装,继承,多态:
  • 类库:
  • 异常处理:

Compile once, run anywhere

  • 利用javac对.java文件进行compile,之后产生.class文件。.class文件包含了??? 。之后我们可以通过javap,也就是jdk自带的反汇编器,来查看.class文件的内容。

    wong@MacBook-Pro Desktop % javap -c Test.class 
    Compiled from "Test.java"
    public class Test {
      public Test();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: iconst_0
           1: istore_1
           2: iconst_0
           3: istore_2
           4: iinc          1, 1
           7: iinc          2, 1
          10: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
          13: iload_1
          14: invokevirtual #13                 // Method java/io/PrintStream.println:(I)V
          17: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
          20: iload_2
          21: invokevirtual #13                 // Method java/io/PrintStream.println:(I)V
          24: return
    }
    

    Java源码首先被编译成java字节码,再由不同平台的JVM进行解析。java语言在不同平台上运行不需要进行重新编译,java虚拟机在执行字节码的时候,再将字节码转换成平台对应的机器指令。

  • JVM如何加载.class文件
    在这里插入图片描述

    上图是JVM的架构图。

    • Class Loader : 依据特定格式,加载class文件到内存
    • Execution Engine : 对命令进行解析
    • Native Interface : 融合不同开发语言的原生库为java所用
    • Runtime Data Area : JVM内存空间结构模型
  • Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的方法和属性;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息和动态调用对象方法的功能成为Java的反射机制

    Class rb = Class.forName("code1.Robot");
    		Robot r = (Robot)rb.newInstance();
    		System.out.println("Class name is " + rb.getName());
    		Method getHello = rb.getDeclaredMethod("throwHello", String.class);
    		getHello.setAccessible(true);
    		Object str = getHello.invoke(r, "Bob");
    		System.out.println("The name is " + str);
    		Field name = rb.getDeclaredField("name");
    		name.setAccessible(true);
    		name.set(r, "Obama");
    		Method sayHi = rb.getMethod("sayHi", String.class);
    		sayHi.invoke(r, "What");
    
  • 类从编译到执行的过程

    • 编译器将.java源文件编译为.class字节码文件
    • ClassLoader将字节码转换为JVM中的Class对象
    • 而从字节码文件传入的数据格式是以byte[]形式传入的
    • 之后JVM通过Class对象实例化为Robot对象
  • ClassLoader在Java中有着非常重要的地位。它主要工作在Class装载阶段,其主要作用是从系统外部获得Class字节码数据流。它是java的核心组件,所有的class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的字节码数据流装载进系统,然后交给Java虚拟机进行连接,初始化等操作。

    • BootStrapClassLoader : C++编写,加载核心库java.*
    • ExtClassLoader : Java编写, 加载扩展库javax.*
    • AppClassLoader : Java编写, 加载程序所在目录
    • 自定义ClassLoader : Java编写, 定制化加载
    public class MyClassLoader extends ClassLoader {
    
    	private String path;
    	
    	private String classLoaderName;
    	
    	public MyClassLoader(String path, String classLoaderName) {
    		
    		this.path = path;
    		this.classLoaderName = classLoaderName;
    	}
    	
    	// Find Class File
    	@SuppressWarnings("deprecation")
    	@Override
    	public Class findClass(String name) {
    		
    		byte[] b = loadClassData(name);
    		return defineClass(b, 0, b.length);
    	}
    
    	// Load Class File
    	private byte[] loadClassData(String name) {
    		name = path + name + ".class";
    		InputStream in = null;
    		ByteArrayOutputStream out = null;
    		try {
    			in = new FileInputStream(new File(name));
    			out = new ByteArrayOutputStream();
    			int i = 0;
    			while( (i = in.read()) != -1) {
    				out.write(i);
    			}
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		} finally {
    			try {
    				out.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			try {
    				in.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		// TODO Auto-generated method stub
    		return out.toByteArray();
    	}
    }
    
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    		MyClassLoader mc = new MyClassLoader("/Users/wong/", "wali.class");
    		Class c = mc.loadClass("Wali");
    		System.out.println(c.getClassLoader());
    		c.newInstance();
    	}
    
    • ASM & 字节码增强技术 & AOP的实现
  • 类加载器的双亲委派机制

在这里插入图片描述

  • 为何要使用双亲委派机制?因为避免同一个字节码文件加载多次,避免占用多余的内存空间

  • 类的加载方式

    • 隐式加载:new
    • 显示加载:loadClass, forName等
    • loadClass与forName的区别:

在这里插入图片描述

GC (Garbage Collection)

酝酿中…

本文地址:https://blog.csdn.net/weixin_41741302/article/details/107335641

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网