【-------------数据类型------------】
一、基本类型、包装类型
基本类型:整型(byte short int long )浮点型(float double)布尔型(boolean) 字符型(char)
包装类型:Byte Short Integer Long Float Double Boolean Character
1.基本类型的转换方式
自动类型转换(小–>大): byte --> short --> int --> long --> float --> double
强制类型转换(大–>小): 小类型 变量名 = (大类型) 值
2.为什么需要包装类型
Java是面向对象的,很多地方要求使用对象而不是基本数据类型,比如集合类中,无法存放基本数据类型
3.基本类型和包装类型的区别
(1)默认值:基本类型默认值为0,包装类型默认值为null
(2)初始化:基本类型不需要new,包装类型需要
(3)存储:基本类型存储在栈上,占用固定的内存;包装类型存储在堆上,占用更多的内存
4.自动拆装箱:基包转换
装箱:基本类型——>包装类型;拆箱:包装类型——>基本类型
装箱其实就是调用了包装类的 valueOf() 方法(Integer.valueOf()),拆箱其实就是调用了 xxxValue() 方法(Integer.intValue())
大小比较:包装类先拆箱成基本类型,然后再进行比较
二、引用类型(类、数组、接口)
1.String
String是一个类,所以是引用数据类型,因为String被final修饰,所以不能被继承。
(1)String/StringBuffer/StringBuilder的区别
【可变性】String内部的value值是final修饰的,所以是一个不可变的类,每一次修改String值时,都会产生一个新的对象;StringBuffer和StringBuilder是可变类,字符串的变更不会产生新的对象。
【线程安全】String是一个不可变的类,所以线程安全,StringBuffer也是线程安全的,因为它的每个操作方法中都用了synchronized同步关键字,StringBuilder不是线程安全的,所以在多线程环境下对字符串操作时应该使用StringBuffer。
【性能】String是性能最低的,因为在字符串拼接或者修改时,需要创建新的对象,StringBuilder性能更高,因为StringBuffer加了同步锁。
【存储】String存储在常量池中,后两者存储在堆内存空间中。
(2)String为什么是不可变的
1.保存字符串的数组被final修饰且为私有的,并且string类没有提供/暴露修改这个字符串的方法。
2.String类被final修饰导致其不能被继承,进而避免了子类破坏String的不可变。
(3)String创建字符串的对象数量
String str = new String ("hello");创建了几个对象?
创建的对象数是1个或2个。new String 会先去常量池中判断有没有此字符串,如果有则只在堆上创建一个字符串并且指向常量池中的字符串,如果常量池中没有此字符串,则会创建 2 个对象,先在常量池中新建此字符串,然后把此引用返回给堆上的对象。
因此推荐使用直接量的方式创建字符串:
String str = "hello";
JVM会检查常量池中是否有hello,没有的话存入常量池,有的话将其引用赋值给变量str
(4)字符串拼接如何实现
+运算符:如果拼接的都是字符串直接量,编译器会直接优化为一个完整的字符串;如果拼接的包含变量,编译时创建StringBuilder实例并调用append()方法
StringBuilder/StringBuffer:拼接的字符串中包含变量,都有字符串缓冲区(默认16),如果超过容量,会有扩容机制。
String的concat():先创建一个数组,先后将两个字符串拼接到数组中,最后将数组转化为字符串
2.接口和抽象类的区别
抽象类属于模板设计。抽象类可以包含抽象方法和具体方法的定义,用于作为其他类的父类。
//动物类可以作为抽象类,因为动物不是具体的,需要通过子类比如猫类、狗类继承
abstract class Animal {
//成员变量:可以拥有各种访问修饰符
static String name;
//构造函数
public Animal() {
}
//抽象方法:以分号结尾,无方法体,必须在子类中实现重写
abstract void eat();
//具体方法:可以拥有各种访问修饰符
public void play() {
System.out.println("玩耍");
}
}
接口是一组抽象方法的集合,体现的是一种规范。接口定义了对象应该具备的行为,类可以实现接口来达到多继承的效果。
public interface Demo{
//常量:必须初始化
public static final String s = "我是接口";
//接口属于实现,不是继承,所以没有构造方法
//抽象方法:必须实现,默认修饰 public abstract
public abstract void play();
//静态方法:可以使用接口名调用静态方法
static void test(){
system.out.println("我是静态方法");
}
//默认方法:为了扩展性和复用性
default void test2(){
system.out.println("我是默认方法");
}
}
(1)定义方式
(1)抽象类:使用关键字“abstract”来定义
(2)接口:使用关键字“interface”来定义
(2)继承和实现
(1)抽象类:使用关键字“extends”来继承,一个类只能继承一个抽象类
(2)接口:使用关键字“implements”来实现,一个类可以实现多个接口
(3)成员变量和构造函数
(1)抽象类:拥有成员变量和构造方法(不用于创建对象,而是初始化抽象类),可以拥有各种访问修饰符
(2)接口:不能拥有成员变量(只能包含静态常量,默认public static final修饰)和构造方法
(4)方法实现
(1)抽象类:包含抽象方法和具体方法
(2)接口:包含抽象方法、静态方法(静态方法是属于接口本身的方法,它可以直接通过接口名调用,而不需要创建接口的实例)和默认方法(默认方法是指在接口中定义具体实现的方法。当接口的实现类没有实现该方法时,就会使用接口中默认的方法实现)、私有方法
(5)相同点
都不能被实例化(不能使用 new 关键字创建实例)
都可以包含抽象方法,实现或继承的时候都必须实现这些抽象方法