问:谈谈你对java的理解?
- 平台无关性(一处编译多处运行)
- GC(垃圾回收机制)
- 语言特性(泛型、反射、lambda表达式)
- 面向对象(封装继承多态)
- 类库(集合、网络库、并发库、nio)
- 异常处理
javac 将.java文件进行编译,编译出.class文件(二进制字节码,包含java类中的属性、方法、常量信息,还会有个共有的静态常量属性.class,这class记录了类的相关信息及类型信息,是class的一个实例)
javap 可反编译class文件 可以查看java编译器生成的字节码
如何跨平台的:
问:jvm如何加载.class文件?
问:谈谈反射?写例子?
理论:Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。
实例:
ps:getDeclaredMethod 公共的私有的包私有的方法(private、protected、public和default),即所有的都可以,但是不能获取到继承的,实现接口的方法
私有方法必须设置 .setAccessible(true)
getMethod 可以获取public方法和继承的方法、实现接口的方法
类从编译到执行的过程:
- 编译器将Robot.java源文件编译为Robot.class字节码文件
- ClassLoader将字节码转换为JVM中的Class
对象 - JVM利用Class
对象实例化为Robot对象
问:谈谈ClassLoader?
理论:ClassLoader在Java中有着非常重要的作用,它主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流。ClassLoader是Java的核心组件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过各种方式将Class信息的二进制数据流读入系统,然后交给Java虚拟机进行连接、初始化等操作。因此,ClassLoader在整个装载阶段,只能影响到类的加载,而无法通过ClassLoader去改变类的连接和初始化行为。
最核心的就是 ClassLoader.java中的loadClass方法
ClassLoader的种类:
- BootStrapClassLoader:C++编写,加载核心库java.*
- ExtClassloader:java编写,加载扩展库javax.*(System.getProperty("java.ext.dirs")可以看到扩展库路径)
- AppClassLoader:java编写,加载程序所在目录(System.getProperty("java.class.path")可以看到加载路径,最重要的是javabasic路径)
- 自定义ClassLoader:java编写,定制化加载(关键函数,findClass、defineClass)
类的加载方式:
- 隐式加载:new
- 显示加载:loadClass、forName等,获取到class对象之后调用newInstance()方法来生成对象实例(newInstance不支持传入参数,需要反射getConstructor然后调用构造器的newInstance方法传入参数)
loadClass和forName的区别:
类的装载过程(加载和生成实例的过程)
Class.forName得到的class是已经完成初始化的
Classloder.loadClass得到的class是还没有链接的
public class Robot { static { System.out.println("Hello Robot"); } }
public static void main(String[] args) throws ClassNotFoundException { //不会初始化 所以没有打印(加快加载速度,延迟加载) ClassLoader cl = Robot.class.getClassLoader(); //会初始化 所以打印了(mysql驱动就是用的这个) Class r = Class.forName("myclassloader.Robot"); }