- 一、JVM、JRE及JDK的关系
- 二、JAVA语言特点
- 三、JAVA和C++的区别
- 四、Java的基本数据类型
- 五、隐式(自动)类型转换和显示(强制)类型转换
- 六、Java的自动装箱与拆箱
- 1、下程序的运行结果
- 2、java是否存在使得语句i>j||i<=j结果为false的i、j值?(没机会见到应该。太恶心了)
- 3、java1.5的自动装箱拆箱机制是编译特性还是虚拟机运行时特性?分 别是怎么实现的?
- 4、java语句Integer i=1;i+=1;做了哪些事情?
- 5、问:下面程序的运行结果是什么?
- 6、谈谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别。
- 七、Java中的string的不可改变性
- 1.可以缓存hash值
- 2.常量池优化
- 3.线程安全
- 八、Java中的String类的常用方法都有那些
- 九、Java中的String和StringBuffer、StringBulider的区别是什么?
- 十、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上
- 总结
一、JVM、JRE及JDK的关系
JDK(Java development kit)是针对java开发员的产品,是整个Java的核心,包括了Java的运行环境JRE、Java工具和Java基础类库。
JRE(Java runtime environment)是运行Java程序所必须的环境的集合,包括JVM标准实现及Java核心类库。
JVM(Java Virtual machine)是Java虚拟机的缩写,是整个Java实现跨平台的最核心的部分,能够运行Java语言写作的软件程序。
直白的说,就是jdk是Java的开发工具,jre是开发程序运行所需要的环境,JVM是Java虚拟机,他们之间的关系是jdk包含jre和jvm,jre包含jvm。
- Java是一种面向对象的语言
- Java通过Java虚拟机实现了平台无关性,一次编译,到处运行
- 支持多线程
- 支持网络编程
- 具有较高的安全性和可靠性
面试时记住前面四个就行
- Java通过虚拟机从而实现跨平台特性,但是C++依赖于特定的平台。
- Java没有指针,它的引用可以理解为安全指针,而C++具有和C一样的指针。
- Java支持自动垃圾回收,而C++需要手动回收。
- Java不支持多重继承,只能通过实现多个接口来达到相同目的,而C++支持多重继承。
- Java不支持操作符重载,虽然可以对两个string对象通过执行加法运算,但是这是语言内置支持的操作,不属于操作符重载,而C++可以。
- Java的goto是保留字,但是不可用,C++可以使用goto。
注意String不是Java的基本数据类型,易混淆
| 类型 | 关键字 | 包装器类型 | 占用内存(字节) (重要) | 取值范围 | 默认值 |
|---|---|---|---|---|---|
| 字节型 | byte | Byte | 1 | -128(-2^7) ~ 127(2^7-1) | 0 |
| 短整型 | short | Short | 2 | -2^15 ~ 2^15-1 | 0 |
| 整型 | int | Integer | 4 | -2^31 ~ 2^31-1 | 0 |
| 长整型 | long | Long | 8 | -2^63 ~ 2^63-1 | 0L |
| 单精度浮点型 | float | Float | 4 | 3.4e-45 ~ 1.4e38 | 0.0F |
| 双精度浮点型 | double | Double | 8 | 4.9e-324 ~ 1.8e308 | 0.0D |
| 字符型 | char | Character | 2 | ‘u0000’ | |
| 布尔型 | boolean | Boolean | 1 | true/flase | flase |
-
隐式类型转换(自动):从存储范围小的类型到存储范围大的类型。
byte→short(char)→int→long→float→double
-
显示类型转换(强制):从存储范围大的类型到存储范围小的类型。
double→float→long→int→short(char)→byte
该类类型转换很可能存在精度的损失
例如:
short s =1; s = s + 1;
运行报错,原因:这里的1是int型,s+1会自动转换成int型,将int型直接赋值给short型会报错。
修改(自动进行强制转换):
short s =1; s += 1;
或
short s = 1; s = (short)(s + 1);六、Java的自动装箱与拆箱
Java的自动装箱:将基本类型用包装器类型包装起来 Java的自动拆箱:将包装器类型转换成基本类型1、下程序的运行结果
public class Main {
public static void main(String[] args) {
Long l1 = 128L;
Long l2 = 128L;
System.out.print(l1 == l2); //1
System.out.print(l1 == 128L); //2
Long l3 = 127L;
Long l4 = 127L;
System.out.print(l3 == l4); //3
System.out.print(l3 == 127L); //
}
}
运行结果:
false true true true
分析:
对于注释1的语句,Long包装类型常量cache为-128到127之间,所以l1和l2
变量是两个对象,== 比较的是对象的地址,所以打印为false。
对于注释2的语句,由于包装类型在表达式中且表达式中至少有一个不是包
装类型,所以Longl1==128L中l1自动拆箱退化为基本类型比较,所以数值
比较为true。
对于注释3的语句,Long包装类型-128到127之间的值维护在一个常量池
中,所以l3和l4引用同一个对象,故打印true。
对于注释4的语句类似注释2语句,所以打印为true。
Double a = Double.NaN; Double b = Double.NaN; System.out.println(a>b||a<=b)
分析:
java中的NaN代表 Not A Nubmer 一个不是数字的数字 (这个题想吐,巨
恶心)。
java1.5开始的自动装箱拆箱机制其实是编译时自动完成替换的,装箱阶段
自动替换为了valueOf方法,拆箱阶段自动替换为了xxxValue方法。
对于Integer、Short、Byte、Character、Long类型的valueOf方法,参数
如果是-128~127之间的值会直接返回内部缓存池中已经存在对象的引用,
参数是其他范围值则返回新建对象;
而Double、Float类型与Integer类型类似,一样会调用Double、Float的
valueOf方法,但是不管传入的参数值是多少都会new一个对象来表达该数
值,因为在某个范围内的整型数值的个数是有限的,而浮点数却不是。
首先 Integer i = 1; 做了自动装箱(使用 Integer.valueOf() 方法将 int 装箱
为 Integer 类型),接着 i += 1; 先将 Integer 类型的 i 自动拆箱成 int(使
用Integer.intValue() 方法将 Integer 拆箱为 int),完成加法运行之后的 i
再装箱成 Integer 类型。
Integer i1 = new Integer(127); Integer i2 = new Integer(127); System.out.println(i1 == i2);//false System.out.println(i1.equals(i2));//true
注意:new Integer(xxx)这种创建对象的方法不是自动装箱,没有用到
cache,因此i1 == i2是false。
1)第一种方式不会触发自动装箱的过程;而第二种方式会触发。
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在
一般性情况下要优于第一种情况(注意这并不是绝对的),因为会用到
cache
在Java 8 中,string内部使用char数组存储数据,并且被声明为final,因此它的不可被继承。
public final class String implements java.io.Serializable, Comparable, CharSequence {
private final char value[];
}
不可变性的好处:
1.可以缓存hash值因为String的hash值经常被使用,例如String用作HashMap的key。不可变得特性可以使得hash值变得不可变,因此只需要进行一次计算。
2.常量池优化String对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的作用。
3.线程安全String不可变性天生具备线程安全,可以在多个线程中安全使用。
八、Java中的String类的常用方法都有那些- length():返回字符串的长度
- charAt():返回指定索引处的字符
- substring():截取字符串
- trim():去除字符串两端空白
- split():分割字符串,返回一个分割后的字符串数组
- replace():字符串替换
- indexOf():返回指定的字符索引
- toLowerCase():将字符串转换成小写字符
- toUpperCase():将字符串转成大写字符
如图所示:
| 可变性 | 线程安全性 | 性能 | |
|---|---|---|---|
| String | 不可变 | 安全 | 低 |
| StringBuffer | 可变 | 不安全 | 高 |
| StringBulider | 可变 | 安全 | 较高 |
switch可以作用在char byte short int 及它们对应的包装类型,switch不可以作用于long double float boolean 及它们的包装类型。在jdk1.5之后可以作用于枚举类型,在jdk1.7之后可以作用于String类型。
总结
不收任何费用!
关注,持续更新



