目录
StringBuffer 和 StringBuilder 类
数据类型
字面值
整形默认为 int 类型,浮点型默认为 double
自动类型转换
注意:布尔类型不参与转换
当把 int 类型赋值给 short 和 byte 不超过范围自动转换,超出范围编译错误
强制类型转换
取低位
循环
增强的for循环
格式
for(type var: collectionName){
// 循环体
}
面向对象的三大特点
- 封装
对象是状态(属性)和行为(操作或方法)封装体。
实现信息隐藏,通过接口与外界通信。 - 继承
一个对象获得另一个对象的属性的过程 - 多态
接口的多种不同的实现方式即为多态
类和对象
方法重载
参数个数或者参数类型不同
静态方法
只能调用静态方法和静态变量
实例方法
只能通过实例名调用
变量初始化顺序:(静态变量、静态初始化块)>(变量、初始化块)>构造器
类成员的访问权限
修饰符 | 同一个类 | 同一个包的类 | 不同包的子类 | 任何类 |
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
pubic | √ | √ | √ | √ |
数组
数组元素的复制
Arrays 类中的复制数组元素的方法,含有 8 种基本类型的方法重载
public static <T> T[] copyOf(T[] original, int newlength)
// original 是原数组,newlength 是新数组的长度,如果 newlength 比原数组的小则取前面若干个
public static <T> T[] copyOfRange(T[] original, int from, int to)
// from 是起始下标,to 是结束下标(不包含)
字符串
两种构造方法的区别
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2)
str1 = new String("abc");
str2 = new String("abc");
System.out.println(str1 == str2);
}
/*
* 输出结果:
* true
* false
*/
第一种是在字符串常量池中创建,相同的常量不会重复创建
第二种是创建两个字符串对象
查找操作
public int indexOf(int ch)
public int lastIndexOf(int ch)
// 找不到则返回 -1
public char charAt(int index)
StringBuffer 和 StringBuilder 类
StringBuffer类的实例是线程安全的
StringBuilder类的实例不是线程安全的
如果不需要线程同步,建议使用StringBuilder类
类的继承
- 子类继承父类非 private 的成员变量和成员方法
- 子类不能覆盖超类的 private 方法
- 父类中 static 方法可以被继承,但不能被覆盖
- 构造函数的调用构造方法必须在构造方法的第一句且只有一句。
- 当子类构造方法中没有 super 语句时自动加上默认构造方法 super() ,如果父类没有默认构造方法,编译错误
-
子类不继承父类的构造方法
final
- final 类不能继承,final 方法不能被子类覆盖
- final 变量一旦赋值就不能改变
instanceof
instanceof 运算符用来测试一个实例是否是某种类型的实例,这里的类型可以是类、抽象类、接口等
方法覆盖
参数列表和返回值均相同(和方法重载区别)
内部类
成员内部类
成员内部类中不能定义static变量和static方法
局部内部类
局部内部类访问所在方法的参数和局部变量都必须使用 final 修饰,外层类的成员不需要 final 修饰
匿名内部类
匿名内部类只能继承一个类或实现一个接口
一般格式
new typename(){ // typename 为继承的类名或者方法名
/* 此处为类体 */ //可覆盖超类或实现接口的方法
}
静态方法
- 使用 static 修饰
- 可以定义静态成员
- 只能访问外层类的静态成员
- 创建静态内部类的实例不需要先创建一个外层类的实例
接口嵌套
在类或接口中还可以定义内部接口。
接口不能被实例化,所以内部接口只有在是静态的时才有意义
自定义注解类型
一般格式
public @interface CustomAnnotation{
// 元素或属性声明
}
- 在注解类型中声明的方法称为注解类型的元素,它的声明类似于接口中的方法声明,没有方法体,但有返回类型。
- 元素的类型有一些限制,如只能是基本类型、String、枚举类型、其他注解类型等,并且元素不能声明任何参数。
- 在定义注解时可以使用 default 关键字为元素指定默认值。
public @interface Version{
int major() default 1;
int minor() default 0;
}
Version注解类型可以用来标注类和接口,也可以供其他注解类型使用。例如,可以用它来重新定义ClassInfo注解类型:
public @interface ClassInfo{
String created();
String author();
String lastModified();
Version version();
}
注解类型中也可以没有元素,这样的注解称为标记注解(marker annotation),这与标记接口类似
public @interface Preliminary {}
如果注解类型只有一个元素,这个元素应该命名为value。例如,Copyright注解类型只有一个String类型的元素,则其应该定义为:
public @interface Copyright {
String value();
}
这样,在为程序元素注解时就可以不需要指定元素名称,而采用一种缩略的形式:
@Copyright("flying dragon company")
接口
- 定义在接口中的任何变量都自动加上 public、final、static 属性,因此它们都是常量,常量的定义可以省略修饰符
- 定义在接口中的任何方法都自动加上public,abstract属性,因此实现接口的时候注意方法不能降低访问权限
静态方法
- 可以在接口中定义静态方法,定义静态方法使用static关键字,默认的访问修饰符是public
- 接口的静态方法不能被子接口继承,也不被实现类继承
- 接口的静态方法使用“接口名.方法名()”的形式访问。静态方法在哪个接口中定义,就使用哪个接口名访问。
默认方法
- 默认方法需要使用 default 关键字定义。
- 默认方法可以被子接口和实现类继承,但子接口中若定义相同的默认方法,父接口的默认方法被隐藏(与静态方法不同)
- 默认方法需要通过引用变量调用
Comparator<T> 接口
public interface Comparator<? super T> {
int compare(T first, T second);
// 其他静态方法和默认方法
}
lambda 表达式
函数式接口定义
在定义函数式接口时可以给接口添加@FunctionalInterface注解,如果接口定义多于一个的抽象方法,编译器会报错,如:
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
lambda 表达式的省略
代码块只有一句返回值语句(不是void类型方法)可以写成
(var1, var2, ...) -> 表达式
表达式类型可推导,可以省去类型
表达式只有一个参数,且类型可推导,可以省去括号
Function<T, R> 接口
public interface Function<T, R>{
R apply(T argument);
}
Predicate<T> 接口
public interface Predicate<T>{
boolean test(T t);
}
Supplier<T> 接口
public interface Supplier<T>{
T get();
}
Consumer<T> 接口
public interface Consumer<T>{
void accept(T t);
}
UnaryOperator<T> 接口
一元运算
public interface UnaryOperator<T> extends Function<T, T> {}
方法与构造方法引用
方法引用:
- 对象::实例方法名
- 类名::静态方法名
- 类名::实例方法名
构造方法引用:
- 类名::new
- 数组::new,如:
int[]::new
泛型
泛型类或接口
public class Node<T>{ // 类或接口
private T a;
}
T 不能是基本数据类型,可以使用像 Integer, Double 这些包装类
泛型方法
如:
public <T> void show(T t){
System.out.println(T)
}
泛型类型本身是一个 Java 类型,为泛型类型传递不同的类型参数会产生 不同的类型 。如: 尽管 String 是 Object 的子类,但 ArrayList<String> 并不是 ArrayList<Object> 的子类型 。
?通配符
// 上界用extends指定,例如,
List<? extends Number> // 表示 Number 的子类或者子接口
// 下界用super指定,例如,
List<? super Integer> // 表示 Integer 的父类或其父类的某种类型
类型擦除
当实例化泛型类型时,编译器使用一种叫类型擦除(type erasure)的技术转换这些类型。在编译时,编译器将清除类和方法中所有与类型参数有关的信息。在运行时找不到泛型类使用的是什么类型。
如:Node<Integer> 被转换成 Node,它称为源类型 (raw type)。源类型不带任何类型参数的泛型类或接口名。下面操作是不可能的。
public class MyClass<E> {
public static void myMethod(Object item){
if (item instanceof E) { // 编译错误
...
}
E item2 = new E(); // 编译错误
E[] iArray = new E[10];// 编译错误
E obj = (E)new Object(); // 非检查的造型警告
}
}
异常处理
try-catch-finally
try{
// 需要处理的代码,可能抛出异常
} catch (ExceptionType1 exceptionObject){ //捕获异常
// 异常处理代码
}[catch (ExceptionType2 exceptionObject){
// 异常处理代码
}]
[finally{ // 最后处理代码
}]
至少有一个 catch 块,finally 块可选,finally 块无论有无异常,是否执行了 return,除了调用 System.exit(),都会执行。
可以使用或运算 ( | )分隔处理多个异常。
方法抛出异常
使用 throws 关键字
returnType methodName([paramlist]) throws ExceptionList{
// 方法体中会有异常抛出
}
调用该方法的方法则需处理异常
throw 语句抛出异常
创建一个异常对象然后抛出
throw exceptInstance;
try-with-resource
可以自动关闭资源
try( 声明和创建某种资源 ) // 只有实现了 java.lang.AutoCloseable 接口的那些资源才可自动关闭。
{
// 使用资源
}
[catch(Exception e){}]
[finally{
}]
自定义异常类
编写自定义异常类实际上是继承一个标准异常类,通常继承 Exception 类,如下所示:
class CustomException extends Exception {
public CustomException(){}
public CustomException(String message) {
super(message);
}
}
assert断言
assert expression ;
assert expression : detailMessage ;
编译时需要使用 –enableassertions 或 -ea 选项
多线程
实现多线程的方法
实现Runnable接口并实现它的 run() 方法
public void run(){}
// 调用 Thread 构造方法
Thread(Runnable target)
Thread(Runnable target, String name)
// 调用 start() 方法
thread.start() // 每个线程只能调用一次
继承Thread类并覆盖它的run()方法
// 调用 Thread 构造方法
Thread()
Thread(String name)
// 调用 start() 方法
thread.start()
比较
继承 Runnable 接口,还可以继承其它类,符合面向对象设计思想
方法同步
在定义方法是使用 synchronized 关键字,自动获得对象的内在锁,在静态方法使用 synchronized 关键字,则获得类锁,如:
public synchronized void increment(){
cnt++;
}
块同步
synchronized(object){
// 方法调用
}
监视器模型
使用一个变量判断对象是否可用
public class Box {
private int data;
private boolean available = false;
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace(System.out);
}
}
data = value;
available = true;
notifyAll();
}
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
available = false;
notifyAll();
return data;
}
static class Consumer implements Runnable {
Box box;
public Consumer(Box box) {
this.box = box;
}
@Override
public synchronized void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Consumer " + box.get());
try {
Thread.sleep((int) (Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace(System.out);
}
}
}
}
static class Producer extends Thread {
Box box;
public Producer(Box box) {
this.box = box;
}
@Override
public synchronized void run() {
for (int i = 0; i < 10; i++) {
int num = (int) (Math.random() * 100);
box.put(num);
System.out.println("producer " + num);
try {
Thread.sleep((int) (Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace(System.out);
}
}
}
}
public static void main(String[] args) {
Box box = new Box();
Consumer c = new Consumer(box);
Producer p = new Producer(box);
Thread thread1 = new Thread(c);
Thread thread2 = new Thread(p);
thread1.start();
thread2.start();
}
}
注意:wait()、notify()、notifyAll(),只能在只能用于 synchronized 代码块中
Executor 和 ExecutorService
Executor 接口
java.util.concurrent.Executor 接口只定义了 execute() 方法
public void execute(Runnable task)
ExecutorService 接口
ExecutorService是 Executor 接口的一个扩展,它添加了关闭方法和提交 Callable 任务的方法
可以使用工具类Executors的静态方法就可得到 Executor 实例
static ExecutorService newSingleThreadExecutor()
static ExecutorService newCachedThreadPool()
static ExecutorService newFixedThreadPool (int numOfThread)
Callable<T> 接口
Callable<V>也是一项任务,定义了一个call()方法,返回一个值,并抛出一个异常。
public interface Callable<V>{
V call() throws Exception
}
要执行Callable任务,也可以使用一个ExecutorService实例,调用它的submit()方法将任务提交给执行器。
ExecutorService executor = Executors.newCachedThreadPool();
Callbale<V> task = ... ;
Future<V> result = executor.submit(task);
通过 Future 的 get() 方法可以获取 Callable<V> 任务(即调用call()方法)的返回值。
public V get() throws InterruptedException, ExecutionException;
public V get(long timeoout, TimeUnit unit) throws ExecutionException, TimeoutException, InterruptedException;
Lock 锁定对象
为了确保unlock()方法总是能被调用,在调用lock()方法之后,用finally子句中调用unlock()方法。
Lock aLock = new ReentrantLock();
...
aLock.lock(); // 加锁
try{
// 临界区
}finally{
aLock.unlock(); // 释放锁
}