1. 基本数据类型

7种基本数据类型
整型,浮点型,布尔型,字符型
三大类
字符型: char
布尔型: boolean
数值型:
1.整型: byte short int long
2.浮点型: float,double

String 不是基本数据类型,是引用类型

整型数据取值范围

类型 占用存储 取值范围 默认值
byte 1个字节 -128 – 127 0
short 2个字节 – 2^15 – 2^15 -1 0
int 4个字节 – 2^31 – 2^31 -1 0
long 8个字节 – 2^63 – 2^63 -1 0

数值溢出不会抛出异常,故需注意数据
如 kylin中sum(int)在大数据量下会计算出负值

浮点数

又有效数字加上幂数表示
并不是所有的十进制小数都能准确的用二进制表示 如0.1
bit 是衡量浮点数所需存储空间的单位 通常是32位或4位,分别叫做单精度 和双精度

保存金额: 使用BigDecimal或Long(单位 分)表示金额

自动拆装箱

基本类型 内置类型
JAVA 是一种强类型语言
第一次申明变量必须说明数据类型,
第一次变量赋值称为变量的初始化
Java 3类基本类型
字符型 char
布尔型 boolean
数值型 byte short int long float double
Java还存在void 对应的包装类 java.lang.Void

基本类型的优势 分配在栈内存中,不像 new的对象 在堆中

包装类型

byte => Byte
boolean => Boolean
short => Short
char => Character
int => Integer
long => Long
float => Float
double => Double

为什么需要包装类
很多地方需要使用对象,为了使基本类型具有对象的特征,为添加属性和方法,丰富基本类型的操作

拆箱与装箱

基本类型包装成 包装类的过程就是 装箱
包装类转换成 基本类型的过程就是 拆箱
在 Java SE5之前 通过 new 包装类(基本类型)Integer i = new Integer(1)

自动拆箱与自动装箱

Java SE5中 增加了自动拆箱与自动装箱的功能
自动装箱:基本数据类型自动转换对应的包装类
自动拆箱:将包装类自动装换成对应的基本类型

Integer i = 1;
int x = i;

实现方式

自动装箱是通过包装类的 valueOf() 方法来实现,
自动拆箱是通过包装对象的 xxxBalue()来实现

常用场景

  • 基本类型放入集合中
  • 包装类与基本类型的大小比较,先拆箱为基本类型再比较
  • 包装类型的运算 包装类型的运算会拆分为基本类型进行计算
  • 三目运算符 三目运算符中,会自动拆箱,若为null,会发生NPE
  • 函数参数与返回值 参数与返回值会自动拆装箱

自动拆装箱与缓存

JAVA5中引入了缓存机制,对整型对象通过使用相同的对象实现缓存和重用
如果一个包装类是
-128 和 127之间的整数
true 和 false 的布尔值
‘\u0000′ 和’\u007f’ 之间的字符可直接判断 是否相等

自动拆装箱的问题

  1. 对象 之间 == 的例外情况
  2. 自动拆箱时的 NPE问题 null
  3. 循环中的大量自动拆装箱浪费很多资源

String

String的不可变性

定义: String s = "a"; s中把偶才能的是"a"在堆中的地址
赋值: String s2 = s; s2保存与s相同的引用地址
连接: s = s.concat("b") s中保存一个新String对象的引用
String对象一旦在内存中创,就无法修改;String对应的所有方法都是放回了一个新的对象
若需要大量修改一个字符串,应尽量使用StringBuffer 或StringBuilder

JDK 1.6 和 1.7 substring的区别

substring(int beginIndex,int endIndex)
截取并返回[beginIndex,endIndex -1]的内容

JDK6 中的substring

JDK6中的 substring 与源string 引用了同一个 cahr[],区别在于其 offset不同
导致问题 使用子串时 会引用 较长的父串 由于无法回收,可能导致内存泄漏

JDK7中修正这一点,使用new 创建一个新的String,不再引用 旧的字符串,避免了内存泄漏

String "+"的重载(语法糖)

String s = 常量1 + 常量2; // 编译器 会自动进行常量折叠
String s = 常量 + 变量; // 用哪个StringBuilder的append方法替换,最后toString,返回一个新的String

字符串拼接

String 的不可变性,字符串的相关操作都是返回了一个新的String
常用的 + 拼接字符串,实际都是 JAVA 提供的语法糖

concat StringBuffer StringBuilder StringUtils.join(JAVA 8)

concat 新建 char[] 赋值 返回 new String
StringBuffer StringBuilder 会将字符拷贝到内部的缓冲区中,缓冲区不够会自动扩展,StringBuffer通过synchronized声明为线程安全
StringUtils.join 使用StringBuilder实现,同时封装其他操作, 更适合字符串数组或列表的拼接

String.valueOf 与 Integer.toString 没有本质区别 String.valueOf 也是调用 Integer.toString

Switch 的String 支持 (jdk 7)

switch 支持 byte short int char String

  1. java 对 byte int 和 short的switch支持 的判断是直接比较值
  2. 对char支持是转换为 ASCII码的 int变量 再进行比较
  3. 对string支持 是先比较hashCode (java中case只能是int,hashCode返回值就是int),由于hash可能碰撞,在内部先做 equals判断

switch 只支持一种数据类型,即 整型

字符串池 常量池 intern

  1. 方法区:存储类信息、常量、静态变量。全局共享。
  2. 堆区:存放对象和数组。全局共享。
  3. 栈区:基本数据类型、对象的引用都存放在这。线程私有。

字符串池(String Pool)
其位置在方法区上面的驻留字符串(Interned Strings)的位置
字符串常量池是全局共享的。字符串调用String.intern()方法后,其引用就存放在String Pool中

  1. 字面量创建字符串会先在字符串池中找,看是否有相等的对象,没有的话就在堆中创建,把地址驻留在字符串池;有的话则直接用池中的引用,避免重复创建对象。
  2. new关键字创建时,前面的操作和字面量创建一样,只不过最后在运行时会创建一个新对象,变量所引用的都是这个新对象的地址

JDK1.6字符串常量池在永久代,1.7移到了堆中,1.8用元空间代替了永久代

java中关键字

关键字 作用 用法
transient 让某些被修饰的成员属性变量不被序列化 序列化类设置不需的字段
instanceof instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例 在编译状态中,class可以是object对象的父类,自身类,子类。在这三种情况下Java编译时不会报错。在运行转态中,class可以是object对象的父类,自身类,不能是子类。在前两种情况下result的结果为true,最后一种为false。但是class为子类时编译不会报错。运行结果为false。
volatile 实现缓存一致性协议,对一个变量的写操作先行发生于后面对这个变量的读操作  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。  2)禁止进行指令重排序。 用于保证写入完成后,下次读取的一定是主内存地址的数据,而不是缓存的数据,但无法保证对多线程下操作的原子性
synchronized 同步锁,锁定具体对象,其他未锁定的对象仍可以读取 多线程读写同一对象数据
final 修饰类、方法和变量,保证其不可变 不可继承类,不可覆盖方法,不可变变量
static 创建独立于具体对象的域变量或者方法,即使没有创建对象,也能使用属性和调用方法 所有对象所共享的变量
const 在Java中,const是作为保留字以备扩充,同样的保留字以备扩充还有goto