Java核心技术卷一
Day01
- [x] P164
安装库源文件和文档
库源文件在jdk/src.zip中
使用jar xvf jdk/src.zip
解压
更多源代码访问网站
文档独立于JDK,需要单独下载
1 | a += b += c //等价于a += (b += c) 右结合运算符 |
不要使用==
来检测两个字符串是否相等,该运算符只能确定两个字符串是否放置在同一位置上
1 | String s1 = "Hello"; |
多态与动态绑定
1 | //Manager是Employee的子类 |
一般情况下,应该尽量少用类型转换和instanceof
hashCode
1 | //hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的存储地址 |
建议自定义类中添加toString方法
自动装箱与自动拆箱
1 | //自动装箱 |
自动装箱规范要求boolean,byte,char<=127,介于 -128~127之间的short和int被包装到固定的对象中。
如果在一个表达式中混合使用Integer和Double类型,Integer就会自动拆箱,提升为double,再装箱为Double
1 | try{ |
- [x] P239
Day02
浅拷贝与深拷贝
1 | //根据对象属性的拷贝程度(基本数据类型和引用类型)分为浅拷贝和深拷贝 |
- [x] 258
内部类
代理
异常
1 | //所有的异常都是由Throwable继承而来,在下一层分解为Error和Exception两个分支 |
派生于RuntimeException的异常包含以下情况:
- 错误的类型转换
- 数组访问越界
- 访问null指针
不是派生于RuntimeException的异常:
- 试图在文件尾部后面读取数据
- 试图打开一个不存在的文件
- 试图根据给定的字符串查找Class对象,但这个字符串表示的类并不存在
规则:如果出现RuntimeException异常,那么就一定是你的问题
- 数组下标越界异常:ArrayIndexOutOfBoundsException
- null指针异常:NullPointerException
Java语言规范将派生于Error类或者RuntimeException类的所有异常称为非受查异常(unchecked),其他异常称为受查异常(checked)
运行时异常,不可查,不需要显示捕捉
可查异常,必须显示捕捉或者抛出
断言和日志
泛型
Java核心技术与面试指南
- [ ] P96
- [ ] P87
- [ ] P107
定义基本数据类型的变量,对象的引用,还有函数调用的现场保存都使用JVM
栈空间
通过new
和构造器创建的对象放在堆空间,堆事垃圾收集器管理的主要区域
栈用光StackOverflowError
堆和常量池不足OutOfMemoryError
- 两个对象相同(equals返回true),则对象的hashCode值一定相同
- 当两个对象的hashCode相同,它们并不一定相同
- equals:
- 自反性(x.equals(x)==true)
- 对称性(x.equals(y)==true)(y.equals(x)==true)
- 传递性(x.equals(y)==true)(y.equals(z)==true)(x.equals(z)==true)
- 一致性(x,y引用的对象信息没有改变时,x.equals(y)返回值不变)
sleep()进入阻塞态 对应TIMED_WAITING
yield()进入就绪态
join() 对应WAITING
两阶段终止模式
InterruptException会重置isInterrupted为false
isInterrupted不会清除打断标记
Interrupted会清除打断标记
Transient:阻止用此关键字修饰的变量序列化,当对象反序列化时该变量不会被持久化和恢复,只能修饰变量
IO流
- 按流向分:输入流和输出流
- 按操作单元分:字节流和字符流
按流的角色分:节点流和处理流
InputStream/Reader:所有输入流的基类,前者字节输入流,后者字符输入流
OutputStream/Writer:所有输出流的基类,前者字节输出流,后者字符输出流
Reader-字符读取
- 节点流
- FileReader(文件操作)
- PipedReader(管道操作)
- CharArrayReader(数组操作)
- 处理流
- BufferedReader(缓冲操作)
- InputStreamReader(转化控制)
- 节点流
- Writer-字符写出
- 节点流
- FileWriter
- PipedWriter
- CharArrayWriter
- 处理流
- BufferedWriter
- OutputStreamWriter
- PrintWriter(打印控制)
- 节点流
- InputStream-字节读取
- 节点流
- FileInputStream
- PipedInputStream
- ByteArrayInputStream
- 处理流
- BufferedInputStream
- DataInputStream(基本数据类型操作)
- ObjectInputStream(对象序列化操作)
- SequenceInputStream
- 节点流
OutputStream-字节读出
- 节点流
- FileOutputStream
- PipedOutputStream
- ByteArrayOutputStream
- 处理流
- BufferedOutputStream
- DataOutputStream
- ObjectOutputStream
- PrintStream
- 节点流
BIO:同步阻塞I/O
- NIO:同步非阻塞I/O
- AIO:异步非阻塞I/O(NIO2)
synchronized
语法
1 | synchronized(对象){ |
1 | public synchronized void test(){ |
private与final提供安全的意义所在,开闭原则中的闭
常见的线程安全类
- String
- Integer等包装类
- StringBuffer
- Random
- Vector
- HashTable
- java.util.concurrent包下的类
这里线程安全是指,多个线程调用同一个实例的某个方法时,是线程安全的,即
- 它们的每个方法是原子的
- 但它们多个方法的组合不是原子的
==与equals():
compareTo():
关于JVM、JDK、JRE
Java虚拟机(JVM)是运行Java字节码的虚拟机,JVM针对不同系统有不同的实现。
Java程序从源代码到运行一般有三步:
*.java文件
—>*.class文件
—>机器可执行的二进制代码
JDK(Java Develpoment Kit),是功能齐全的Java SDK,拥有JRE的一切并且还有编译器(javac)和工具(如javadoc和jdb),能够创建和编译程序。
JRE是Java运行时环境,是运行已编译Java程序所需所有内容的集合,包括JVM,Java类库,Java命令和其他的基础构件,不能创建新程序。
关于重写(override)与重载(overload)
重载
完整描述一个方法,需要指出方法名和参数类型,这就是方法的签名。当多个方法有相同名字、不同参数就会产生重载。返回类型不是方法签名的一部分。
重写
子类对父类的允许访问的方法的实现进行重新编写,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
关于封装、继承、多态
封装
封装是把一个对象的属性私有化,并提供一些可以被外部访问的属性的方法。
继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或功能,也可以使用父类的功能。
需要注意的三点:
- 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但父类中的私有属性和方法子类无法访问,只是拥有。
- 子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
多态
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。
在Java中有两种方式实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。
继承与实现
继承与组合
Java只有值传递
成员变量和方法作用域
- default:表明该成员变量或者方法只有自己和其位于同一个包的内可见,其他包内的类不能访问,即便是它的子类。
- public:表明该成员变量或者方法是对所有类或者对象都是可见的,所有类或者对象都可以直接访问。
- protected:表明成员变量或者方法对类自身,与同在一个包中的其他类可见,其他包下的类不可访问,除非是他的子类。
- private:表明该成员变量或者方法是私有的,只有当前类对其具有访问权限,除此之外其他类或者对象都没有访问权限.子类也没有访问权限。
关于接口和抽象类
在Java中,接口不是类,而是对类的一组需求描述,并且不能通过new实例化一个接口,但是可以声明接口的变量,接口变量必须引用实现了接口的类对象。
接口中方法默认标记为
public
,域标记为public static final
每个类只能继承一个抽象类,但是可以实现多个接口
关于==与equals
==:作用是判断两个对象的地址是否相等。若对象是基本数据类型时比较对象的值,若对象是引用数据类型则比较内存地址。
equals:作用是判断两个对象是否相等,若类没有覆盖equals方法,此时equals相当于==;若类覆盖了equals方法,则通过equals来比较对象的内容是否相等。
关于hashCode与equals
只有在HashMap、HashSet、HashTable等本质是散列表的数据结构中使用对象时,hashCode和equals才有关系,此时需要重写hashCode和equals。
对象相同,hashCode一定相同
hashCode相同,对象不一定相同