在这里记录一下自己回顾Java基础时,一些觉得掌握的还不牢固的基础知识,查漏补缺!
Java程序初始化顺序
三个原则
- 静态对象优先于非静态对象,静态对象只会初始化一次
- 父类优先于子类
- 成员变量则是根据定义的顺序进行初始化
各种代码块的初始化顺序则如下:
- 父类静态变量,静态代码块
- 子类静态变量,子类静态代码块
- 父类费静态变量,代码块
- 父类构造方法
- 子类非静态变量,代码块
- 子类构造方法
Java对象的作用域
成员变量:作用范围与类的实例对象的作用范围相同
静态变量:只要一个类被加载,jvm就会给该类的静态变量分配存储空间
局部变量:仅限于该类所在的花括号内
构造方法
当父类没有提供无参的构造方法时,子类的构造方法中必须显式的调用父类的构造方法;
当提供了无参构造方法,则无需显式调用,因为编译器会默认调用父类无参构造方法;
在实例化对象时,先执行父类的构造方法,然后才是子类
clone方法的理解
- 首先,为什么会有该方法?
这里涉及到Java方法的两种传递参数方式:
处理基本数据类型时,采用的是按值传递;
此外,当处理其他数据类型时,都是采用的按引用传递,包括在使用“=”赋值时也是如此
这样就会导致一个问题:当需要创建一个和当前已有对象相同的对象,又需要对其中一个的修改不会影响到另一个对象时,使用一般的赋值操作显然无法达到该目的,因此提供了clone方法来提供这个能力
- 如何实现clone方法?
在将这个之前,先看两个概念:
浅复制:被复制的对象的所有变量都和原来的对象有相同的值,而所有对其他对象的引用仍然指向其原来的对象;
深复制:会将原对象所有引用的对象全都复制一遍
下面看如何实现clone方法:
- 使目标类实现Cloneable接口,该接口中没有任何方法,只是一个标识接口
- 重写clone()方法
- 在该方法中返回super.clone(),也就是会调用至Object的clone方法
上面是浅复制的实现方法,若需实现深复制,则需要对对象中的非基本类型数据都调用clone方法;
注意,这里需要这些属性所属类全都实现clone方法才行
组合和继承
继承:is-a的关系
组合: has-a关系
能使用就尽量不要使用继承
多态
Java中的多态主要表现为两种方式:
- 方法的重载overload:编译时多态,在编译期间就可以确定调用哪一个方法
- 覆盖override:运行时多态,只有在运行时,才可以确定内存中实例化的是哪一个对象
这里需要注意:只有方法才有多态的概念,类中的成员变量并没有方法的概念,因为成员变量是在编译期间就确定了的;
因此,成员变量的取值为new对象定义的类型的值
举例如下:
BaseClass b = new SubClass()
假设sub是base的子类,这时打印b.age,此时打印出的是base中定义的值而非sub定义
接口与抽象类
接口,强调功能的特定实现,是has-a的关系
抽象类,强调所属关系,是is-a的关系
static代码块常用来初始化静态变量
switch支持string类型,其实也是先判断字符串的hashcode是否相同,若相同, 再调用equals方法进行匹配
volatile
可以提供可见性,部分有序性,但是无法保证原子性,因此其还是无法替代synchronized关键字
按值传递与引用传递
- 值传递:原始数据类型,会拥有不同的存储空间,对参数的修改不会影响到原值
- 引用传递:传递的是对象的地址,二者指向同一内存地址,对形参的修改会影响到实参
Java的异常处理用到了多态的概念,在进行异常捕获时,如果需要捕获多个,应该先捕获子类,再捕获基类;
否则若顺序相反,子类异常就不会被捕获到了
网友评论