文章目录
重写 & 重载
Java 重写(Override)与重载(Overload)
-
重载(overload):函数方法名必须相同,参数列表(参数个数和类型)不同
-
编译时多态,返回类型,访问权限不能作为重载的依据
-
目的:用相同的名字表示功能相似的函数,减少名字空间的污染,有利于程序的可读性
public abstract class MyClass { public int constInt = 5; public void method() {} // 以下写法是错误的 public int method(); }
-
重载规则
- 被重载的方法必须改变参数列表(参数个数或类型不一样)
- 可以改变 返回类型、访问修饰符、声明新的或更广的 检查异常
- 方法能够在 同一个类 中或者在一个子类中被重载
-
-
重写(override):子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变
-
运行时多态
-
重写规则:两同两小一大
-
方法名相同,参数类型相同
-
子类
返回类型
小于等于父类方法返回类型, -
子类
抛出异常
小于等于父类方法抛出异常,- 父类的一个方法申明一个检查异常 IOException,但在重写方法的时候不能抛出 Exception 异常
- 因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常
- 父类的一个方法申明一个检查异常 IOException,但在重写方法的时候不能抛出 Exception 异常
-
子类
访问权限
大于等于父类方法访问权限。
-
-
不能被重写
- 构造方法
- 声明为 final 的方法
- 声明为 static 的方法不能被重写,但是能够被再次声明
-
基本类型 & 包装类型
基本类型 | 包装类型 | |
---|---|---|
null | × | √ |
泛型 | × | √ |
高效 |
- 可以为 null 值 使得包装类型可以应用于 POJO 中,而基本类型则不行
- 数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出 NullPointerException 的异常 --《阿里巴巴 Java 开发手册》
- 泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类
- 基本类型是个特例
- 基本类型在栈中直接存储的具体数值;而包装类型则存储的是堆中的引用,占用更多的内存空间
自动装箱和自动拆箱
Java为每种基本数据类型都提供了对应的包装器类型
- 装箱(boxing) :基本类型转换成包装类型的过程
- 自动装箱是通过
Integer.valueOf()
完成
- 自动装箱是通过
- 拆箱(unboxing):把包装类型转换成基本类型的过程
- 自动拆箱是通过
Integer.intValue()
完成的
- 自动拆箱是通过
// 1)基本类型和包装类型进行 == 比较,这时候 b 会自动拆箱,直接和 a 比较值,所以结果为 true
int a = 100;
Integer b = 100;
System.out.println(a == b);
// 2)两个包装类型
Integer c = 100;
Integer d = 100;
System.out.println(c == d);
// 3)
c = 200;
d = 200;
System.out.println(c == d);
//-128 到 127 之间的数会从 IntegerCache 中取,然后比较,所以第二段代码(100 在这个范围之内)的结果是 true
//第三段代码(200 不在这个范围之内,所以 new 出来了两个 Integer 对象)的结果是 false
https://www.cnblogs.com/dolphin0520/p/3780005.html
//从Java SE5开始就提供了自动装箱的特性
Integer i = new Integer(10);
Integer i = 10;
装箱和拆箱是如何实现的
- 在装箱的时候自动调用的是Integer的valueOf(int)方法
- 在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
- Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现:都会生成新对象(同float
- 在某个范围内的整型数值的个数是有限的,而浮点数却不是。
- Boolean若值相同则都会复用之前已创建的
- 在拆箱的时候自动调用的是Integer的intValue方法。
Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别
1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;
2)在执行效率和资源占用上的区别(可从复用与否考虑
- 第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)
可变类 不可变类
- 可变类:当获得这个类的一个实例引用时,可以改变这个实例的内容
- 不可变类:当获得这个类的一个实例引用时,不可以改变这个实例的内容
- 不可变类的实例一但创建,其内在成员变量的值就不能被修改
- 所有 成员 都是
private final
- 不提供对成员的改变 方法,例如:setXXXX
- 确保所有的方法不会被重载,手段有两种
- 使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)
- 确保所有的方法不会被重载,手段有两种
- 多线程安全
- 在多线程同时进行的情况下,一个可变对象的值很可能被其他进程改变,这样会造成不可预期的结果,而使用不可变对象就可以避免这种情况
== & equals
- ==
- 基础数据类型:比较的是他们的
值
是否相等- 比如:两个int类型的变量,比较的是变量的值是否一样
- 引用数据类型:比较的是引用的
地址
是否相同- 比如:新建了两个User对象,比较的是两个User的地址是否一样
- 基础数据类型:比较的是他们的
- equals
- 引用数据类型:比较的是引用的
地址
是否相同 - 重写了equals(),如 String、Date :比较的是字符串的
内容
是否一样
- 引用数据类型:比较的是引用的
System.arrayCopy() & Arrays.copyOf()
- Arrays.copyOf()
- 不仅只是拷贝数组中的元素,在拷贝元素时,会创建一个新的数组对象
- 该方法的底层还是调用了System.arrayCopyOf()
- System.arrayCopy()
- 只拷贝已经存在数组元素
- 如果改变目标数组的值原数组的值也会随之改变
String & StringBuffer & StringBuilder
Java中的String,StringBuilder,StringBuffer三者的区别
- 运行速度(执行速度):
StringBuilder > StringBuffer > String
- String 最慢的原因:
- String为字符串常量,而StringBuilder和StringBuffer均为字符串变量
- 即 String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的
- 另外两个对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多
- 线程安全:
StringBuilder
是线程不安全的,而StringBuffer
是线程安全的 - 如果要进行的操作是多线程的,使用StringBuffer
- 在单线程的情况下,还是建议使用速度比较快的StringBuilder