文章目录
零 基础概念
0 有关Java
- 编译型语言会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言的执行速度比较快,开发效率比较低。
- 解释型语言会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。
- Java是编译与解释并存的语言。由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行。字节码对应.class文件,它是面向JVM而非特定系统的,具有良好的可移植性。
1 JVM / JDK / JRE
- JVM(Java virtual machine):运行 Java 字节码(.class格式文件)的虚拟机,针对不同系统有不同的实现。JVM是一种规范,满足规范的虚拟机都可称为JVM。
- JDK(Java development kit):功能齐全的 Java SDK。拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序。
- JRE(Java runtime environment):Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。但是不能用于创建新程序。
总之,JDK 包含 JRE 包含 JVM。
2 与C++的联系和区别
- 都是面向对象的语言,支持封装、继承、多态;
- Java 不提供指针来直接访问内存,程序内存更加安全;
- Java 的类是单继承的(接口支持多重继承),C++ 支持多重继承;
- Java 有自动内存管理垃圾回收机制;
- C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载。
一 Java语法
1 各类型数据占用空间大小
Java中比较特殊的是char类型占用2字节(16bits)
2 可变长参数
下面的方法可以接受0或多个参数,可变长的形式参数只能放在参数列表的末尾,在实现时会被视为数组。
public static void printVariable(String... args) {
for (String s : args) {
System.out.println(s);
}
}
3 静态方法与实例方法
- 静态方法属于类,因此静态方法可以不创建实例使用。最好使用 类名.方法名 的方式调用。
- 同样的,静态方法只能访问别的静态方法与静态成员变量,不能访问非静态成员。
4 重载和重写
- 重载:相同的方法名,不同的参数列表。可以发生在一个类中,也可以发生在父类和子类间。重载就是同一个类中多个同名方法根据不同的传参来执行不同的逻辑处理。重载发生在编译时。
- 重写:相同的方法名,相同的参数列表。发生在父类和子类间,本质上是子类覆盖了父类的方法。重写发生在运行时。
重写要实现的目的是,父类方法能完成的事,子类重写后不能完成得更差。具体指的是:抛出异常的类型更小或相等,返回值的类型更小或相等(如果方法的返回类型是 void 和基本数据类型,则返回值重写时不可修改。但是如果方法的返回值是引用类型,重写时可以返回该引用类型的子类),访问权限更大或相等。
5 泛型
- 泛型的本质是参数化类型,即数据类型被指定为一个参数。
- Java 的泛型是伪泛型,因为 Java 在运行期间,所有的泛型信息都会被擦掉(类型擦除) 。
- 具体使用时,有泛型类、泛型接口、泛型方法。
6 == 和 equals() 的区别
- 对于基本数据类型,只能用 == 比较。
- 对于引用数据类型, == 用于比较内存地址; equals() 如果未被重写,也是比较内存地址,重写后按照指定规则判断两个对象是否相等。
7 hashCode() 方法
- 重写 equals() 方法时,必须同时重写 hashCode() 方法。
- 两个对象的 hashCode 值相等并不代表两个对象就相等(哈希碰撞)。两个对象相等则 hashCode 必相等。
- 两个对象的比较,首先比较 hashCode() 的返回值是否相等,如果不相等直接认为两个对象不相等,如果相等则继续调用 equals() 方法,返回 True 时视为两个对象相等。
- 如果重写 equals() 时没有重写 hashCode() 方法的话,可能会导致 equals 方法判断是相等的两个对象,hashCode 值却不相等。
- hashCode() 存在的意义是,减少 equals() 的调用,提高执行速度。
8 包装类型
- 包装类型的比较必须用 equals() 。
- 包装类型不赋值就是 Null ,而基本类型有默认值且不是 Null。
- 基本数据类型直接存放在 Java 虚拟机栈中的局部变量表中,而包装类型属于对象类型,存在于堆中。相比于对象类型, 基本数据类型占用的空间非常小。 补充:局部变量表主要存放了编译期可知的基本数据类型 、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
- Java 基本类型的包装类的大部分都实现了常量池技术。 Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False。Float,Double 并没有实现常量池技术。
- 装箱与拆箱:装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。
Integer i = 10; //装箱,等价于 Integer i = Integer.valueOf(10)
int n = i; //拆箱,int n = i.intValue()