java复习

本文概述了Java编程中的关键概念,包括数据类型及其转换规则,控制结构(如循环和增强for循环),面向对象编程的三大特点(封装、继承和多态),以及重要的并发工具如Executor和ExecutorService、Callable接口和Lock。文章还介绍了异常处理和线程管理等内容。
摘要由CSDN通过智能技术生成

目录

数据类型

字面值

自动类型转换

强制类型转换

循环

增强的for循环

面向对象的三大特点

类和对象

方法重载

静态方法

实例方法

类成员的访问权限

数组

数组元素的复制

 字符串

两种构造方法的区别

查找操作

StringBuffer 和 StringBuilder 类

类的继承

final

instanceof

方法覆盖

内部类

成员内部类

局部内部类

匿名内部类

静态方法

接口嵌套

自定义注解类型

接口

静态方法

默认方法

Comparator 接口

lambda 表达式

函数式接口定义

lambda 表达式的省略 

Function 接口,>

Predicate 接口

Supplier 接口

Consumer 接口

UnaryOperator 接口 

方法与构造方法引用

方法引用:

构造方法引用:

泛型

泛型类或接口

泛型方法

?通配符 

类型擦除

异常处理

try-catch-finally

方法抛出异常

throw 语句抛出异常

try-with-resource

自定义异常类

assert断言

多线程

实现多线程的方法

实现Runnable接口并实现它的 run() 方法

继承Thread类并覆盖它的run()方法

比较

方法同步

 块同步

监视器模型

 Executor 和 ExecutorService

Executor 接口

ExecutorService 接口

Callable 接口

 Lock 锁定对象


数据类型

字面值

整形默认为 int 类型,浮点型默认为 double

自动类型转换

注意:布尔类型不参与转换

当把 int 类型赋值给 short 和 byte 不超过范围自动转换,超出范围编译错误

强制类型转换

取低位


循环

增强的for循环

格式

for(type var: collectionName){
    // 循环体
}

面向对象的三大特点

  1. 封装
    对象是状态(属性)和行为(操作或方法)封装体。
    实现信息隐藏,通过接口与外界通信。
  2. 继承
    一个对象获得另一个对象的属性的过程
  3. 多态
    接口的多种不同的实现方式即为多态

类和对象

方法重载

参数个数或者参数类型不同

静态方法

只能调用静态方法和静态变量

实例方法

只能通过实例名调用

变量初始化顺序:(静态变量、静态初始化块)>(变量、初始化块)>构造器

类成员的访问权限

修饰符同一个类同一个包的类不同包的子类任何类
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 类的主要区别是

        StringBuffer类的实例是线程安全的

        StringBuilder类的实例不是线程安全的

如果不需要线程同步,建议使用StringBuilder


类的继承

  1. 子类继承父类非 private 的成员变量和成员方法
  2. 子类不能覆盖超类的 private 方法
  3. 父类中 static 方法可以被继承,但不能被覆盖
  4. 构造函数的调用构造方法必须在构造方法的第一句且只有一句。
  5. 当子类构造方法中没有 super 语句时自动加上默认构造方法 super() ,如果父类没有默认构造方法,编译错误
  6. 子类不继承父类的构造方法

final

  1. final 类不能继承,final 方法不能被子类覆盖
  2. final 变量一旦赋值就不能改变

instanceof

instanceof 运算符用来测试一个实例是否是某种类型的实例,这里的类型可以是类、抽象类、接口等

方法覆盖

参数列表和返回值均相同(和方法重载区别)


内部类

成员内部类

成员内部类中不能定义static变量和static方法

局部内部类

局部内部类只在它定义的块内 有效,同局部变量一样,在 定义 它的块之外不能访问,因此也 不能有任何访问修饰符
局部内部类访问所在方法的参数和局部变量都必须使用 final 修饰,外层类的成员不需要 final 修饰

匿名内部类

匿名内部类只能继承一个类或实现一个接口

一般格式

new typename(){  // typename 为继承的类名或者方法名
    /* 此处为类体 */  //可覆盖超类或实现接口的方法
}

静态方法

  1. 使用 static 修饰
  2. 可以定义静态成员
  3. 只能访问外层类的静态成员
  4. 创建静态内部类的实例不需要先创建一个外层类的实例

接口嵌套

在类或接口中还可以定义内部接口。

接口不能被实例化,所以内部接口只有在是静态的时才有意义

自定义注解类型

一般格式

public @interface CustomAnnotation{
      // 元素或属性声明
}
  1. 在注解类型中声明的方法称为注解类型的元素,它的声明类似于接口中的方法声明,没有方法体,但有返回类型。
  2. 元素的类型有一些限制,如只能是基本类型、String、枚举类型、其他注解类型等,并且元素不能声明任何参数。
  3. 在定义注解时可以使用 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")

接口

  1.  定义在接口中的任何变量都自动加上 publicfinalstatic 属性,因此它们都是常量,常量的定义可以省略修饰符
  2. 定义在接口中的任何方法自动加上publicabstract属性,因此实现接口的时候注意方法不能降低访问权限

静态方法

  1. 可以在接口中定义静态方法,定义静态方法使用static关键字,默认的访问修饰符是public
  2. 接口的静态方法不能被子接口继承,也不被实现类继承
  3. 接口的静态方法使用“接口名.方法名()”的形式访问。静态方法在哪个接口中定义,就使用哪个接口名访问

默认方法

  1. 默认方法需要使用 default 关键字定义。
  2. 默认方法可以被子接口和实现类继承,但子接口中若定义相同的默认方法,父接口的默认方法被隐藏(与静态方法不同)
  3. 默认方法需要通过引用变量调用

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> {}

方法与构造方法引用

方法引用:

  1. 对象::实例方法名
  2. 类名::静态方法名
  3. 类名::实例方法名

构造方法引用:

  1. 类名::new
  2. 数组::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();     // 释放锁
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值