-
基本数据类型及其包装类
-
基本数据类型 空间大小(字节) 默认值 包装类 byte 1 0 Byte short 2 0 Short int 4 0 Integer long 8 0L Long float 4 0.0F Float double 8 0.0D Double char 2 u0000(null) Character boolean 1(数组中)或4(单独) false Boolean -
包装类是引用数据类型,所以其默认值为null
-
boolean类型在JVM编译后,如果是单独使用,JVM会使用int型数据代替boolean型数据,所以占4字节,如果是一个boolean型的数组,JVM会使用byte数字代替boolean数组,那么数组中的每一个boolean型数据占1字节
-
-
装箱和拆箱(包装类的装箱拆箱方法类似,下面以int和Integer来演示)
-
装箱
-
将基本数据类型的数据转化成对应包装类型的数据
-
//Integer的静态方法valueOf(int i)装箱 int num = 1; Integer integer = Integer.vauleOf(num);
-
-
拆箱
-
将包装类型的数据转化成对应基本数据类型的数据
-
//Integer类的实例方法intValue(Integer integer)来完成拆箱 Integer integer = new Integer(6); int num = integer.intValue(integer);
-
-
-
自动装箱和自动拆箱在java SE5之后实现
-
自动装箱 (int —> Integer)
-
自动将基本数据类型的数据转化成对应的包装类型的数据
-
//自动装箱机制 Integer integer = 5;
-
-
自动拆箱 (Integer —> int)
-
自动将包装类型的数据转化成对应的基本数据类型的数据
-
Integer integer = new Integer(5); //自动拆箱机制 int num = integer;
-
-
-
== 是一个结果为布尔值的运算符,而equlas是返回值为布尔值的一个实例方法,故==可以比较基本数据类型的数据和引用类型的数据,但equals只能比较引用数据类型的数据
-
如果两个基本数据类型的变量使用 == 进行比较时,==判断的是两个变量指向的值是否相等,相等返回true,不等返回false,而如果是两个引用数据类型的变量使用 == 进行比较时,==判断的是这两个变量内存中存放的对象的内存地址是否相同,相同(同一个对象)返回true,否则返回false
-
equals方法来源于超级父类Object类,下面是equals方法的源代码
-
public boolean equals(Object obj) { return (this == obj); }
-
从源码中可以看出,Object类的equals方法是使用==进行比较的,所以比较的是两个对象的内存地址
-
因此如果一个类没有重写equals方法,该类实例化的两个对象使用equals进行比较时,会使用Object的equals方法,即比较的是两个对象的内存地址是否相同,相同返回true,不同返回false,如果该类重写了equals方法,那么在使用equals方法进行比较时,会根据重写的比较规则进行比较。
-
-
注意⚠️
- 两个引用数据类型使用==进行比较时,左右的数据类型必须是同一类型或者具有继承、实现关系才能能够编译通过,否则无法编译。
-
//String部分源代码 public final class String implements java.io.Serializable, Comparable
,CharSequence{ private final char value[]; } //StringBuffer和StringBuilder的父类AbstractStringBuilder抽象类的部分源码 abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; } -
从以上String类、StringBuffer和StringBuilder类的父类AbstractStringBuilder类的部分源码可以看出
- String对象底层是一个使用了final修饰的char数组,所以String对象一旦创建就不可改变,每次看似对String对象的更改实质上是创建了一个新的String对象
- String对象的每次 + 拼接操作,实际上是创建了一个和原字符串相同的StringBuilder对象,再调用append方法拼接 + 后面的字符
- StringBuffer和StringBuilder底层都是可变字符数组,因此在对字符串进行频繁的拼接操作时,建议使用StringBuffer或StringBuilder来进行操作。
- StringBuffer类中的大多数方法都使用了synchronized关键字修饰,即加了同步锁,所以是线程安全的,而StringBuilder没有对方法加同步锁,所以是非线程安全的
- java异常结构简图
-
Throwable类是java语言中所以错误和异常的超类,下一层分为Error和Exception
- Error
- Error类是指java运行时系统的内部错误或资源耗尽错误,编译器不会对错误进行检查,一旦程序抛出该类对象,无法通过修改程序来修复这些错误,出现就会导致系统终止运行
- Exception
- 编译时异常
- Exception类本身以及Exception子类中除了RuntimeException分支下的类之外的所有类都属于编译时异常
- java编译器会检查编译时异常,必须实现对该类异常进行处理(try-catch 或者throws),否则无法通过编译
- 运行时异常
- RuntimeException类及其子类都属于运行时异常,运行时异常java编译器不会检查,即即使存在该异常,程序也能够编译通过,只有在程序运行后才会中断程序运行并抛出
- 编译时异常
- 继承Thread类,重写run()方法
- Thread本身实现了Runable接口,代表一个线程的实例,启动线程的唯一方法是通过Thread类的start()实例方法,start()方法是一个native方法,他会启动一个线程,并执行run()方法
- 直接实现Runnable接口,实现run()方法
- Runnable是一个接口,所以哪怕一个类已经继承了其他类,仍然可以通过实现Runnable接口来创建线程
- 实现Callable接口,实现call()方法
- Callable是一个接口,这种方法创建线程和实现Runnable接口创建线程的区别是call()方法有返回值,且可以抛出异常
- 基于线程池创建线程
- java中的四个线程池
- CachedThreadPool
- FixedThreadPool
- ScheduledThreadPool
- SingleThreadExecutor
- java中的四个线程池
你能顺溜的说出问题的答案吗…