- java的数据类型
基本数据类型:
byte | 1个字节 | -2^7~2^7-1 | 0 | 8 bit | Byte |
short | 2个字节 | -2^15~2^15-1 | 0 | 16 bit | Short |
int (默认int ) | 4个字节 | 有符号-2^31~2^31-1 无符号 0~ 2^31-1 | 0 | 32 bit | Integer |
long | 8个字节 | -2^63~2^63-1 | 0.0L | 64 bit | Long |
float | 4个字节 | 0.0f | 32 bit | Float | |
double(默认double) | 8个字节 | - | 0 | 64 bit | Double |
char | 2个字节 | 0~2^16 | \u000 | 16 bit | Character |
boolean | 未定 | false | Boolean |
阿里巴巴规范手册中规定 12L 即long 类型初始化要使用大写的 L来标识位数 = 8bit*字节数
引用数据类型
|
自动装箱拆箱
装箱:将基本数据类包装成引用数据类型
Integer integer = 10 è Integer integer = Integer.valueof(10)
拆箱:将包装对象转换成基本数据类型
Int num = integer è int num = integer.intValue();
IntegerCache
范围 -128 ~ 127 在此范围内只要两个Integer的对象值一样则它们 == 和 equels均为true. int和Integer 、 new Integer()比较 只要值一样 则 == 和equels 结果均为true
- 值传递和引用传递
值传递:
实参传递给形参的值,(字面量的拷贝),实参和形参再内存上是两个独立的变量,对形参的修改不会影响实参的值
引用传递:
实参是传递给形参的是堆内存上引用的地址,(堆中地址拷贝)形参和实参在内存上指向的是同一地址,对形参的改变会影响实参
- 重载和重写
重载:在同一个类中对同一个方法进行重载,方法名相同,参数列表不同(个数、类型不同),发生在编译时,返回值类型无关,即返回值类型可以相同,也可以不同。例如println()方法
可以有不同的访问修饰符,
可以抛出不同的异常,
必须具有不同的参数列表
重写:在有继承关系的类中的方法名,参数,返回值和被重写的方法一样,但是方法体的内容不同。
参数列表、返回值必须与被重写的方法相同
不能抛出比被重写方法更大、更多的异常
访问修饰符范围不能小于被重写的方法
返回值类型的范围不能小于被重写的方法
- 抽象类和接口
1.抽象类内部可以有普通方法(方法的实现细节),而接口中只能存在public abstract方法;
2.抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3.接口中不能含有静态代码块以及静态方法,而抽象类中可以有静态代码块和静态方法;
4.一个类只能继承一个抽象类,而一个类可以实现多个接口。
5.抽象类,有类的特性,即有构造器,但不能直接实例化(可以使用匿名内部类),接口不能有构造器
(阿里巴巴规范手册:接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。)
- JVM
Java虚拟机,JVM内存分为虚拟机栈、堆、方法区、程序计数器、本地方法栈;
其中方法区和堆是线程共享的,虚拟机栈、本地方法栈、程序计数器是线程私有的。
线程是CPU调度的基本单位。在多线程情况下,当线程数超过CPU数量或CPU内核数量时,线程之间就要根据 时间片轮询抢夺CPU时间资源。也就是说,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器去记录其正在执行的字节码指令地址。
因此,程序计数器是线程私有的一块较小的内存空间,其可以看做是当前线程所执行的字节码的行号指示器。如果线程正在执行的是一个 Java 方法,计数器记录的是正在执行的字节码指令的地址;如果正在执行的是 Native 方法,则计数器的值为空。
程序计数器是唯一一个没有规定任何 OutOfMemoryError(内存溢出) 的区域。
Native()方法:本地方法,有专门的本地方法栈,主要用于加载文件和动态链接库,由于Java语言无法访问操作系统的底层信息,需要借助C语言来完成,被Native修饰的方法可以被C语言重写。
虚拟机栈
描述的是Java方法执行的内存模型,是线程私有的。每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,而且 每个方法从调用直至完成的过程,对应一个栈帧在虚拟机栈中入栈到出栈的过程。其中,局部变量表主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和 对象句柄,它们可以是方法参数,也可以是方法的局部变量。
虚拟机栈有两种异常情况:StackOverflowError 和 OutOfMemoryError
本地方法栈
与Java虚拟机栈非常相似,也是线程私有的,区别是虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈为虚拟机执行 Native 方法服务。与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和 OutOfMemoryError 异常。
Java 堆
的唯一目的就是存放对象实例,几乎所有的对象实例(和数组)都在这里分配内存。Java堆是线程共享的,类的对象从中分配空间,这些对象通过new、newarray、 anewarray 和 multianewarray 等指令建立,它们不需要程序代码来显式的释放。
由于Java堆唯一目的就是用来存放对象实例,因此其也是垃圾收集器管理的主要区域,故也称为称为 GC堆。从内存回收的角度看,由于现在的垃圾收集器基本都采用分代收集算法,所以为了方便垃圾回收Java堆还可以分为 新生代 和 老年代 。
方法区
与Java堆一样,也是线程共享的并且不需要连续的内存,其用于存储已被虚拟机加载的 类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区通常和永久区(Perm)关联在一起,但永久代与方法区不是一个概念,只是有的虚拟机用永久代来实现方法区,这样就可以用永久代GC来管理方法区,省去专门内存管理的工作。根据Java虚拟机规范的规定,当方法区无法满足内存分配的需求时,将抛出 OutOfMemoryError 异常
运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存放编译期生成的各种 字面量 和 符号引用。
Java堆和方法区的区别
Java堆是 Java代码可及的内存,是留给开发人员使用的;而非堆(Non-Heap)是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存 (如JIT编译后的代码缓存)、每个类结构 (如运行时常量池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
- 泛型
本质:参数化类型,即给类型指定一个参数,然后使用时再指定此参数具体的值,这个类型就可以使用时决定了。也就是说所操作的数据类型被指定为一个参数
分为:泛型类、泛型接口、泛型方法
泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,如:List、Set、Map
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中
泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。
- HashMap原理
- 序列化
抛出了NotSerializableException异常,表示没有序列化异常如果想把一个对象写到硬盘中,该对象对应的类必须实现Serializable接口
Serializable接口没有属性也没有方法,我们把这种接口称为Marker Interface(标志性接口)
其主要作用就是告诉jvm该类的对象可以被序列化
在写入对象时,会根据类的特征计算一个值serialVersionUID当读取时会根据类再次计算uid值,然后两个比较,如果相等则成功读取,否则抛异常如果想序列化和反序列化时类不一样,需要手动指定serialVersionUID值,如果程序员手动指定了serialVersionUID值,jvm就不会计算该值了。
public static final long serialVersionUID = 1L;
transient 修饰的成员变量不被序列化;
只能修饰变量,不能修饰方法和类
被static修饰的变量不参与序列化,不管是否被transient修饰,均不能序列化。
final变量值参与序列化,final和transient同时修饰变量,final不会影响transient,一样不会参数与序列化。
public static class TransientTest implements Serializable{
private static final long serialVersionUID = 233858934995755239L;
private String name1;
private transient String name2;
public TransientTest(String name1,String name2){
this.name1 = name1;
this.name2 = name2;
}
public String toString(){
return String.format("TransientTest.toString(): name1=%s,name2=%s", name1,name2);
}}
抽象类和接口能放非final对象
抽象类可以放非final对象
接口:
接口是对抽象类的进一步抽象
接口就是某个事物对外提供的一些功能的声明,通过interface关键字完成
1、接口中所有的属性默认为:public static final。。。;
2、接口中所有的方法默认为:public abstract。。。;