Java QuickStart 系列是个人学习 Java 的入坑笔记。
基础
数据类型
基本数据类型:数值型(byte、short、int、long、float、double),字符型(char),布尔型(boolean)
引用数据类型:类,接口,数组
自动转换
也叫扩大转换
转换前后数据类型兼容
转换后的数据类型表示范围比转换前大 如,short 类型转换为 int 类型
任何数据类型碰到 String 类型,都会向 String 类型转换
强制转换
也叫显式转换,可能会丢失精度
1 | float f = 33.3f |
null
null 表示引用数据类型的默认值
面向对象
Java 内存区域
栈内存空间,保存所有对象名称(保存了引用堆内存空间地址)
堆内存空间:保存每个对象的具体属性内容
全局数据区:保存 static 类型的属性
全局代码区:保存所有方法定义
this 关键字
使用 this 调用本类中的属性:this.name = “”
this() 可以用来调用构造方法
this 表示当前实例化的对象
static 关键词
使用 static 表示类属性
static 方法不可以调用非 static 类型的属性和方法
可以在 Class 中声明 static { 静态代码块 },它会优于主方法执行
内部类
在类内部可以通过 public 或 private 声明内部类,访问权限与变量和方法完全相同。
在类中定义内部静态类
在方法中定义内部类
super()
子类默认会自动调用父类的无参构造。super()。
子类可以手动调用父类的有参构造 super(参数)
final
使用 final 声明的类不能有子类
使用 final 声明的方法不能被子类覆盖
使用 final 声明的变量即成为常量,常量不可以修改。
抽象类
包含一个抽象方法的类必须是抽象类,都要使用 abstract 关键字声明
抽象方法只需要声明,不需要实现。抽象方法不能使用 private 声明
public abstract void print();
接口
接口可以理解为一种特殊的类,是由全局常量和公共的抽象方法组成。并且默认是这样,所以声明时候可以简化。
接口的抽象方法必须定义 public 权限
克隆
实现 Cloneable 接口,并覆写 clone() 方法
class Person implements Cloneable {
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
多态性
多态主要体现两方面:
- 方法的重载与重写
- 对象的多态性
对象的多态性,分为向上转型,向下转型。
向上转型,程序会自动完成。
向下转型,必须明确指明要转型的子类类型。
向上转型关系发生以后,调用的方法是子类覆盖后的方法。并且无法调用子类独有的方法。
instance of
用于判断一个对象是否是一个类的实例
返回 boolean
抽象类和接口的区别
1 | 区别点 抽象类 接口 |
Object 类
所有的类都有一个公共的父类,Object。有以下主要方法: equals()、hashCode()、toString();
Object 类提供的 equals() 方法默认是比较地址的
比如 String 类就继承了Object类,单独覆盖实现了 equals() 方法
既然Object是所有对象的父类,则所有的对象都可以向 Object 进行转换(向上转型),即一切引用数据类型都可以使用 Object 进行接收
包装类
Java设计中提倡一切皆对象。
所以需要将基本数据类型进行包装:
1 | int -> Integer |
其中数值类型包装类,主要又继承自 Number 类。它提供一些拆箱方法。
基本数据类型与包装类的互转,称为装箱与拆箱操作。
1 | int x = 30; |
包装类运用最多的,还是进行字符串数值转换,如:
1 | string str1 = "30"; |
异常
如果不对异常进行正确的处理,则可能导致程序的中断执行。
如果没有异常处理,就必须要用大量的判断语句。
定义方法时 throws 关键字表示此方法不处理异常,交给方法调用者进行处理
throw 表示抛出异常
可以直接使用 Exception 捕获所有异常,但是捕获范围小的异常必须放在捕获大的异常之前。
e.printStackTrace();
Throwable
- Exception 表示程序中出现的问题,可以用 try…catch处理
- Error JVM 错误,程序无法处理
包
import * 不会产生性能问题。
如果在不同的包中,有类重名,那么调用的时候需要写出完整的包、类名称。
常用的系统开发包:
java.beans
java.math
java.lang 基本包,目前JDK已经自动导入
java.lang.reflect 反射机制
java.util 工具包,包含常用的类库,重点掌握
java.text 提供了文本处理的类库
java.sql 数据库操作
java.net 网络编程,http、socket、cookie、ip
java.io 输入输出
java.nio
java.security 安全相关,加密算法等
javax.imageio 图形相关
javax.sound 声音相关
javax.xml XML相关
import static 可以静态导入全部使用static声明的静态方法的类。这时候比较像某些语言的函数,因为可以直接使用静态方法调用。
权限控制
private 仅限本类访问
default 可以被本包中的其他类访问
protected 可以被本包及不同包的子类访问
public 所有
应用
多线程
Java 每次运行至少启动2个线程,每当使用Java命令执行一个类时,实际会启动一个JVM,每个JVM就是一个进程,同时启动两个线程:main线程,gc线程。
多线程是指在一个进程执行过程中可以产生多个线程。这些线程可以同时存在,同时运行。
继承Thread类,覆写run方法,通过start执行:
1 | class MyThread extends Thread { |
实现 Runnable 接口,实现run方法:
1 | class MyThread implements Runnable { |
建议使用 Runnable 接口实现多线程,原因:
- 继承 Thread 类,不能实现资源共享。
- 避免 Java 单继承特性带来的局限
- 增强程序健壮性
中断线程 interrupt()
休眠线程 sleep()
后台运行线程 setDaemon()
暂停线程 yield()
同步与死锁
同步:多个操作在同一时间只能有一个线程进行,其他线程要等待此线程完成之后才可以继续运行。
同步代码块
1 | synchronized (this) { |
同步方法
1 | public synchronized run() { |
死锁:两个线程都在彼此等待,过多的同步就有可能产生死锁。
死锁的解决办法:
- 避免过多的同步
- 确保加锁的顺序一致
- 提供加锁的超时时间
IO
java.io包中的流主要有字节流、字符流两大类。字节流对应OutputStream/InputStream,字符流对应Writer/Reader类,它们均是抽象类。
字节流操作时不会用到缓冲区,是文件本身直接操作,而字符流使用了缓冲区。比如字符流如果不进行flush()和close()操作,数据会丢失。
字节字符流的转换,是通过OutputStreamWriter/InputStreamReader类来实现的。而Writer类是OutputStreamWriter子类。所以不管是字符流还是字节流,最终都是以字节的形式输入输出的。
管道流,主要作用是可以进行两个线程间的通信。
打印流,是输出信息最方便的类。