Tomcat中为什么使用自定义加载器?
Tomcat去部署应用的时候,可能会有两个类的类名完全一样,即使两者的内容完全不一样,但Tocat是通过WebAppClassLoader去加载自己的类的,因为在加载完第一个类之后,想要再去加载同名的另一个类是不能实现的,因此我们可以分别有两个不同的类加载器使加载类名一样的类,目的就是为了让应用和应用之间、应用和Tomcat之间的类去进行隔离,不相互冲突。同时Tomcat还可以通过自定义加载类实现热加载过程。
JDK、JRE、JVM之间的区别
- JDK,Java标准开发包,它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行时环境、以及常用的Java类库等
- JRE,Java运行环境,用于运行Java字节码文件,普通用户可以通过JRE来运行Java程序,但是开发者必须安装JDK来遍历、调试程序
- JVM,Java虚拟机,是JRE的一部分,也是整个Java实现跨平台的核心部分,负责运行字节码文件
Java代码想要运行,就需要先编译成字节码,这一过程需要编译器,因此JDK中包含了编译器javac,编译后的字节码想要可以运行,就需要一个可以执行字节码的程序,这个程序就是JVM(java虚拟机)
因此,如果我们要开发Java程序,那就需要JDK,因为要编译Java源文件,当然JDK还给我们提供了类库;如果我们只是想运行已经编译好的Java字节码文件(比如说从同事那边拿字节码文件,想要运行下),那么只需要JRE。JDK中包含了JRE,JRE中包含了JVM。另外JVM在执行Java字节码文件后会将字节码解释为机器语言,而不同的操作系统的机器语言是不一样的,所以在安装JDK时需要选择操作系统。
hashCode()与equals()之间的关系
在Java中,每个对象都可以调用hashcode()方法得到自己的hash值,因此在比较两个对象是同一个对象时,可以利用hashcode做提前的判断,比如:
- 如果两个对象的hashcode不相同,这两个对象肯定是不同的对象
- 如果两个对象的hashcode相同,不代表两个对象一定是同一个对象,也有可能是两个对象
- 如果两个对象是同一个对象,那么他们的hashcode就一定相同
因此在Java一些集合操作中,在比较两个对象是否是同一个对象时,会先调用两个对象的hashcode()方法得到两者的hashcode来进行比较,如果hashcode不相同,就可以直接认为这两个对象不相同,如果hashcode相同,那需要进一步通过equals()方法来进行比较,而equals()方法是最终确定两个对象是不是相等的,通常equals方法的实现是比较笨重的,逻辑也相对复杂,但hashcode的实现其实就是返回一个哈希值,也就是一个数字,相对比较轻,所以在比较两个对象时,通常会根据hashcode先比较下。
所以我们需要注意,在重写equals()方法后,一定要重写hashcode()方法,才能保证遵守上面的规则。
String、StringBuffer、StringBuilder的区别
- String是不可变的,如果尝试去修改一个String类型的值,它会产生一个新的字符串对象,拿下述代码来说,字符串a首先指向"lxl",在完成a
= “lbw"之后,“lxl"并没有被覆盖为"lbw”,而是字符串a指向了"lbw”;相比之下StringBuffer和StringBuilder是可变的。
String a = "lxl"
a = "lbw"
- String是不可变的,显然是线程安全的;StringBuffer是线程安全,StringBuilder是线程不安全的,所以在单线程的环境下StringBuilder的效率会更高。
== 和 equals方法的区别
- ==:如果是基本数据类型(long / int / short / byte / float / double / char / boolean),比较的是值。如果是引用数据类型(类、接口、数组、枚举、注解、字符串、String),比较的是引用地址。
- equals:具体看各类重写equals方法后的比较逻辑,比如String类,虽然是引用类型,但是String类重写了equals方法,它的底层实现是依次比较每一位的字符是否相同。