Java Learning

zihanlizi

2022/04/15

Java learning notes.

JetBrains JavaDeveloper

–20220511

Paradigms

Different approaches to creating programs are called paradigms.

Imperative

Declarative

类与对象

方法

public class 三_1 {
int m=10,n;//正确,成员变量的操作只能放在方法中,声明时可以赋初值
n=100;//报错,赋值只能放在方法中,不能在类体
}

构造方法

默认有一个无参数构造函数,但是如果指定了有参数的构造函数,就需要自己写一个无参数的

java中的构造函数无指定默认参数功能,但可以通过方法重载实现:

class  Lader{
    private double up, down, height, size;
        double laderSize(){
        //返回面积
        size=(up+down)*height/2;
        return size;
    }
//Java支持方法重载,间接实现构造函数默认参数,
// 因此没有如C++中默认参数的功能
    Lader(double u, double d){
        up=u;
        down=d;
    }

    Lader(double u, double d, double h){
        up=u;
        down=d;
        height=h;
    }
}

this

表示某个对象,可以出现在实例方法和构造方法中

局部变量

实例成员与类成员

可变参数

class E_4{

    public static void main(String args[]){
        f(1,2);
        f(-2,-2,-3,-4);
    }
    public static void f(int ... x){//x是可变参数的代表,代表若干个int型参数
        for(int i=0;i<x.length;i++)
            System.out.println(x[i]);//类似数组,代表第i个参数
    }
}

Java Library

ArrayList

format

format("%d",42);

42

format("%.3f",42.00000000);

42.000

format("%.3f",42.00000000);

42.000

format("%c",42); //42表示 char "*" *

子类与继承

子类is a 父类

class Sum{
    //...
}
class Average extends Sum{
    //...Sum的子类
}

子类的继承性

在同一包:除了private

不同包:除了private 和 default,即继承protected 和public

权限由高到低:public protected default private

成员变量的隐藏与方法重写

成员变量的隐藏

子类声明的成员变量名字与从父类继承来的成员变量名字相同,类型可以不同

子类继承的方法只能操作子类继承和隐藏的成员变量

子类重写或新增的方法能操作子类继承和新声明的成员变量,不能操作隐藏的成员的变量

重写 override

super

super必须是子类构造方法的第一句

调用被隐藏的成员变量与方法

默认调用父类不带参数的构造方法

final

抽象

抽象类

如Animals类。不应该被实例化,因此定义为抽象类,让其无法被new

抽象类可以有抽象方法和非抽象方法

抽象方法

必须被重写的方法,which has no body! 没有大括号

public abstract void eat();

上转型对象

多重继承

接口 interface

public interface Pet{
    void beFriendly();
    public abstract void play();
    //接口所有方法默认为public abstract,可以省略
}
public class Dog extends Canine implements Pet{
    //...
}

default 实例方法(必须是public)(不可以省略default,可以省略public) (不可以定义default的static方法)//jdk8

static 方法//jdk8

private 方法//jdk9

  1. 一个class可以implements 多个interface

class Dog extends Animal implements Eatable,Sleepable{}

  1. 重写接口中的方法
  1. 可以用接口名访问接口的常量、调用接口中的static方法
  2. 接口的细节

接口的继承

interface Com{
  int M=200;
  int f();
}
class ImpCom implements Com{
  //错! 返回类型改变,参数类型未改变
  public double f(){
  return 2.6;
  }
  
  //正确
  public int f(){
  return M+100;
  }
}

接口回调

把接口实现的类创建的对象引用赋值给接口声明的变量,那么该接口变量可以调用被类实现的方法以及接口提供的default方法。

多态性

方法重载

将子类对象的引用放进父类: 上转型对象a: 不能访问子类新增的方法和变量 A a = new B()//B为子类

内部类和异常类

内部类

指一个类中定义的另一个类

匿名类

 abstract class Bank{
    int money;
    public Bank(){
        money =100;
    }
    public Bank(int money){
        this.money=money;
    }
    public abstract void output();
}
 class ShowBank{
    void showMess(Bank bank){
        bank.output();
    }
}
class Example{
    public static void main(String[] args) {
        ShowBank showBank = new ShowBank();
        showBank.showMess(new Bank() {//匿名类的类体
            @Override
            public void output() {
                money += 100;
                System.out.println(money);
            }
        });
        showBank.showMess(new Bank(500) {//匿名类的类体
            @Override
            public void output() {
                    money+=100;
                System.out.println(money);
            }
        });
    }
}

异常类

try catch finally

try{
    turnOvenOn();
    x.bake();
}catch (BakingException ex){
    ex.printStackTrace();//recover code
}finally{
    turnOvenOff();
}

throw抛出异常

throws声明异常

public class BankException extends Exception{
    String message;
    public BankExceltion(int m ,int n){
        message="入账资金"+ m +"是负数或支出"+ n +"是正数,不符合系统要求";
    }
    public String warnMess(){
        return message;
    }
}
public class Bank{
    //...
    public void income(int in,int out)throws BankException{
        if(in<=0||out>=0||int+out<=0){
            throw new BankException(in,out);
        }
    }
    //...
}

异常分类

可控异常(检测型异常):预期可能发生的,必须 处理

执行时异常:可以不处理

断言

assert booleanExpression; 若表达式booleanExpression的值为true,程序继续执行,否则程序立刻结束执行。

assert booleanExpression; 若表达式booleanExpression的值为true,程序继续执行,否则程序立刻结束执行,并输出messageException的值。

常用使用类

正则表达式

e.g.

''\\dcat';
\d //元字符,表示0-9中任意数
public boolean matches(String regex){}//regex表示正则表达式
//调用:
str.matches(regex);//判断字符串是否与正则表达式匹配
replaceAll();
public String split(String regex);//使用参数指定的正则表达式regex作为分隔标记
StringTokenlizer对象是一个分析器

GUI

Three ways to put things on GUI:

  1. put widgets on a frame
  2. draw 2D graphics on a widget
  3. put a JPEG on a widget

Saving objects

Serializable 可串行化的

Use an ObjectOutputStream(from the java.io package) to serialize an object.

Note

a interface known as a marker or tag interface: doesn’t have methods to implement

Most classes will and should, implements Serializable

announce an class is serinalizable -> objects of the type saveable

superclass serializable -> subclasses serializable automatically

transient

an instance variable as transient if it can’t (or shouldn’t) be saved.

Exception

否则,在一个Srializable 的类中有非Srializable 的 instance variable会引起错误。

import java.net.*; 
class Chat implements Serializable { 
    transient String currentID;
	String userName;
	// more code
}

Questions

Question

How is a non-serializable instance saved?

  • If you serialize an object, a transient reference instance variable will be brought back as null, regardless of the value it had at the time it was saved.

  • To solve this:

  1. Reinitialize the null null instance variable back to some default state.
  2. Save the key values and use them to essentially re-create a brand new variable that’s identical to the original.

What happens if two objects in the object graph are the same object?

Serialization knows when two objects in the graph are the same.

In that case, only one of the objects is saved, and during deserialization, any references to that single object are restored.

Writing a String to a Text file

import java.io.*;

class WriteAFile {
  public static void main(String[] args) {
    try{
     FileWriter writer = new FileWriter("Foo.txt");//若文件不存在,会自动创建
     writer.write("hello foo!");//必须是str
     writer.close();
    }catch (IOException ex){
       ex.printStackTrace();
    }
  }
}

常用实用类

String

正则表达式

字符序列的替换

String str = "12hello567bird".replaceAll("[a-zA-Z]+","你好"; 将 “12hello567bird"中的所有英文字符替换为"你好”

字符序列的分解

split(String regex)用正则表达式作为分割标记

StringTokenlizer类

Scanner类

  1. Scanner类对象

    • 可以调用方法useDelimiter(正则表达式),以正则表达式作为分割标记。如果不指定分割标记,则以空白字符作为分割标记。(空格,制表符,换行符)
    • next()方法依次返回解析的单词
    • nextInt()或nextDouble()代替next方法:将数字型单词转化为int或double
    • 若单词不是数字,使用nextInt()或nextDouble()将出现异常。
  2. Scanner与StringTokenlizer

输入和输出流

运行可执行文件:runtime

文件字节

文件字符

更好地支持Unicode

缓冲流

BufferedReader和BufferedWriter

FileReader无法每次读取一行。而缓冲流可以。

随机流RandomAccessFile

构造方法:

  1. RandomAccessFile(String name, String mode)
  2. RandomAccessFile(File file, String mode)

mode:r(只读),rw(读写)

seek(long a)方法:

定位流的读写位置,a确定距离文件开头的字节个数

Java多线程机制

12.2 Java中的线程

12.5 线程同步

synchronized(同步)修饰方法。

当一个线程A使用synchronized方法时,其他线程想使用这个方法就必须等待,直到A使用完。

12.6

wait()方法可以暂时中断线程的执行。

如果其他线程使用同步方法不需要等待,则使用完后应用notifyAll()通知其他处于等待的线程。

notify则只通知某一个线程。