谈谈你以Java的理解
平台无关性:一次编译,到处运行,归功于JVM
GC:垃圾回收机制,不需要像C++开发人员那样手动回收
语言特性:泛型,反射,lamda表达式等
面向对象:封装,继承,多态
类库:集合,并发库,IO, NIO等
异常处理:Java 内置异常类
Compile Once, Run Anywhere如何实现?
编译期
通过Javac将.java文件编译成字节码并存入到.class文件。
常用命令:java, javap -c
image.png
运行期
JVM将字节码.class文件加载到内存,转换成操作系统可以识别的指令。
JVM如何加载.class文件
image.png
Class Loader: 根据特定格式,加载.class文件到内存
Execution Engine :执行引擎,对命令进行解析
Heap: 堆, 共享区域
Method Area: 方法区, 共享区域
Stack: 线程栈,线程私有
PC Register: PC计数器 线程私有
Native Method Stack:本地方法栈,线程私有
Native Interface: 本地接口,引用不同开发语言的原生库为JAVA所用,主要语言是C/C++
Native Libraies: 本地库, C/C++接口
谈谈反射
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
简单示例:
package com.bootdubbo.controller;
public class Hello {
private String name;
public String visite(String who) {
return "hello " + who;
}
private String welcome(String str) {
return "welcome " + name;
}
}
package com.bootdubbo.controller;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
// 类全路径
Class cla = Class.forName("com.bootdubbo.controller.Hello");
// 获取对象,返回一个泛型对象,需要强制转换
Hello hello = (Hello) cla.newInstance();
Field nameField = cla.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(hello, "Tom");
// 可以获取类上的所方法,不管是public还是private修饰的
Method welMethod = cla.getDeclaredMethod("welcome", String.class);
// 默认false,必须设置成true
welMethod.setAccessible(true);
Object res = welMethod.invoke(hello, "we");
System.out.println(res);
// 获取public方法,也可以获取继承自己父类的方法
Method visiteMethod = cla.getMethod("visite", String.class);
Object res1 = visiteMethod.invoke(hello, "Jey");
System.out.println(res1);
}
}
类从编译到执行的过程
编译器(javac)将.java源文件编译为.class字节码文件
ClassLoader将.class字节码文件转换成为JVM中的Class对象
JVM根据Class对象实例化为T对象
谈谈ClassLoader
ClassLoader在java中起着非常重要的作用,主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流,它是java的核心部件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载进系统,然后交给java虚拟机进行连接,初始化等操作.
ClassLoader的种类:
BootStrapClassLoader: 用C++编写,加载核心库java.*
ExtClassLoader: