内容纲要

image-20220108212445732

image-20220108213339771

JDK:Java Development Kit

JRE:Java Runtime Environment

Java SE:主要用于桌面应用程序开发。(JDK和JRE)

Java EE:开发企业级分布式的网络程序。(SE,EJB,JSP,XML)

Java ME:针对消费类的电子设备。

运行过程

解释执行:字节码转机器码

解释编译:保存翻译好的机器码(只对经常使用的热代码编译)。加快执行速度。

常用工具

javac——将java编写的程序编译成字节码

java——执行java字节码

jdb——测试和运行小程序

javap——反编译编译后的Java文件,打印字节码

Javadoc——分析Java源程序中的声明和文档注释,并生成关于Java源文件的html页面

javah——将C编写的源代码置于Java程序中

jar——将Java类和其他资源文件捆绑成一个单一的jar文件

//生成文档
Javadoc -d .\api test.java
//jar cvf 压缩后的文件 压缩前的文件
jar cvf after.jar before/*

程序模式

image-20220108213314804

编写事项

image-20220108213444187

命名规范

image-20220108213809554

数据类型

image-20220108213909689

image-20220108213925586

image-20220108214011872

image-20220108214338688

byte b = 123;   
short b = 123;
//编译器帮助完成强制转换,此时b都为int。
int i = 123;
byte b = i;
//需手动写强制转换。
char ch = '中';    //char可以存储汉字
//在算术运算过程中,运算结果至少是int型。
public class Work5 {
    public static void main(String[] argvs){
        byte a = 1,b = 6;
        byte c = a + b;     //报错,a+b为int
    }
}

变量生命周期

image-20220108215131508

//类中方法定义了同名的变量,则方法内变量覆盖类变量。
public class T{
    int x;
    public int f(){
        int x=2;
    }
}

//在同一个方法函数中,变量不能重复定义
public class T{
    public static void main(String[] args){
        int x = 12;
        {
            int x = 3;  //wrong!
        }
    }
}

引用类型

数组

无标题-2022-01-08-2017

//不规则数组
int b[][] = new int[2][];
b[0] = new int[3];
b[1] = new int[5];
int a[][] = {
    {1,2,3},
    {1,2,3,4,5}
};

String

String s = 'cumt';
String s = new String('cumt');

enum

enum Name{赵,钱,孙,李}  //没有分号
public class N{
    Name x = Name.赵;
}
//枚举类型
Name x[] = Name.values();
//Name[0]-Name[3]=赵,钱,孙,李

var

//动态类型
var a = 20;
//只能用于局部变量。
//声明时必须初始化,且以后不能再赋初始值。
//不能用作方法参数。
public class T{
    public static void main(String[] argvs){
        for(var v:argvs){
            ...
        }
    }
}

运算符

5%2=1;
5%-2=1;
-5%2=-1;
-5%-2=-1;

double a=5.2,b=3.1;
double c=a%b=2.1;

image-20220108223041566

标准I/O

输入

//读一个字符import java.io.*;public class ReadT{    public static void main(String args[]) throws IOException {        char ch = (char)System.in.read();        System.out.println(ch);    }}import java.util.Scanner;public class Work5{    public static void main(String args[]){        Scanner scanner = new Scanner(System.in);        int number = scanner.nextInt();        String str;        str = scanner.next();        System.out.println(str);    }}

输出

System.out.println  //打印一行并换行System.out.print   //不换行System.out.printf  //同C

循环

for循环功能扩充

//for中必须是变量声明,不可以使用已经生命过的变量int[] a = {1,2,3,4};for(int i:a){...}    //right!int b;for(b:a){...} //wrong!!

continue

//带标签标记的continueimport java.util.Scanner;public class Work5{    public static void main(String args[]){        jmp:            for(int i=0;i<10;i++){                for(int j=0;j<10;j++){                    System.out.print(j);                    if(j==3){                        continue jmp;                    }                }            }    }}

初始化块

image-20220108233348193

参数传递

public class Work5{
    int x = 5;
    public void change(Work5 w){
        w = new Work5();
        w.x = 3;
    }
    public static void main(String args[]){
        Work5 w = new Work5();
        w.x = 5;
        w.change(w);
        System.out.println(w.x);
    }
}
//5

public class Work5{
    int x = 5;
    public void change(Work5 w){
        w.x = 3;
    }
    public static void main(String args[]){
        Work5 w = new Work5();
        w.x = 5;
        w.change(w);
        System.out.println(w.x);
    }
}
//3

可变参数

//用...表示
static int sum(int... numbers){
    for(int i:numbers){...}
}
//如果一个方法还有其他的形参,只有最后一个形参可以被定义成可变参数形式。
//所有实参都被保存在一个和形参同名的数组里。

修饰符

image-20220108234554665

image-20220108234757187

静态引用

import static可以引入类中的静态成员,类名加或不加都可以。

import static 类名.静态成员/import static 类名/*

单例模式

image-20220108235332829

image-20220108235350317

堆数组

image-20220108235537110

继承

extends实现java单继承

一个子类只能继承自一个父类,如果没有继承任何父类,则自动继承java.lang.Object,Object是所有类的顶级父类。

子类拥有父类的所有属性和方法(覆盖或重写),但父类中说明为private的属性和方法子类不可以直接访问。

如果子类中新定义的静态成员变量与父类中的某个静态成员变量同名,则这两个静态成员变量相互独立。

static final:要在定义时就给定初始值或在static块中给定。

image-20220109203944572

编译时类型由声明该变量时使用的类型(引用的类型)决定

运行时类型由实际赋给该变量的对象的类型(实例的类型)决定。

class Father{
    public void Show(GrandSon obj){System.out.println("FG");}
    public void Show(Father obj){System.out.println("FF");}
}
class Son extends Father{
    public void Show(Son obj){System.out.println("SS");}
    public void Show(Father obj){System.out.println("SF");}
}
class GrandSon extends Son{
    public void Show(GrandSon obj){System.out.println("GG");}
    public void Show(Son obj){System.out.println("GS");}
}

public class Work5{

    public static void main(String[] args){
        Father f1 = new Father();
        Father f2 = new Son();
        Son s1 = new Son();
        GrandSon gs1 = new GrandSon();
        f1.Show(s1);
        f2.Show(s1);
        f2.Show(gs1);
        s1.Show(gs1);
    }
}
/*
FF
SF
FG
FG
*/
//编译后,f1-Fahter,f2—Father,s1-Son,gs1-GrandSon

//运行时,f2变为Son类,但只拥有编译时类型的Show(Father)、Show(GrandSon),而其Show(Father)方法被Son类的Show(Father)进行覆盖;
//s1-Son拥有继承的Father的方法与自己的重载方法;gs1同s1

instanceof

判断该变量属于哪个类

class sup{}
class sub extends sup{}
public class Work5{

    public static void main(String[] args){
        sup sp1 = new sub();
        sup sp2 = new sup();
        sub sb1 = new sub();
        System.out.println("sp1 instanceof sub: "+(sp1 instanceof sub));
        System.out.println("sp1 instanceof sup: "+(sp1 instanceof sup));
        System.out.println("sp2 instanceof sub: "+(sp2 instanceof sub));
        System.out.println("sb1 instanceof sup: "+(sb1 instanceof sup));
    }
}
/*
sp1 instanceof sub: true
sp1 instanceof sup: true
sp2 instanceof sub: false
sb1 instanceof sup: true
*/
//可见运行时,sp1为sub类,同时sub对象也属于sup类

多态

动态绑定

当采用动态绑定调用方法,虚拟机会调用引用对象的运行时类型的那个类的方法。

image-20220109205818720

注意:动态绑定方法不能被final,private,static(private和static可通过编译,但是静态绑定)修饰。

static

子类中的方法如果有着和父类中相同的static方法,如果将子类对象赋给父类引用,通过父类调用同名static方法,则引用的是父类的static方法,子类的同名static方法被隐藏。

class sup{
    static void show(){System.out.println("in supclass");}
}
class sub extends sup{
    static void show(){System.out.println("in subclass");}
}
public class Work5{

    public static void main(String[] args){
        sup sp1 = new sub();
        sup sp2 = new sup();
        sub sb1 = new sub();
        sp1.show(); //in supclass
        sup s = sb1;
        s.show();   //in supclass
    }
}
class sup{
    static{
        System.out.println("sup static");
    }
    void show(){

        System.out.println("in supclass");
    }
}
class sub extends sup{
    static{
        System.out.println("sub static");
    }
    void show(){
        super.show();
        System.out.println("in subclass");
    }
}
public class Work5{
    static{
        System.out.println("Work5 static");
    }
    public static void main(String[] args){
        System.out.println("This is main.");
        sup sp1 = new sub();
        sup sp2 = new sup();
        sub sb1 = new sub();
        sp1.show();
        sb1.show();
    }
}
/*
Work5 static
This is main.
sup static
sub static
in supclass
in subclass
in supclass
in subclass
*/

可以看到,首先加载Work5类,运行static块,接着加载main方法,对第一条sup sp1 = new sub();进行sub类的加载。加载sub类,先跳转到super()-sup类中,执行static块,加载sup的方法;再跳回到sub类,执行static块,加载sub方法进行增加或覆盖。接着执行sp1.show();回到sub::show()中,先调用了super.show()再输出,输出两条信息。

class sup{
    int i=5;
    void show(){
        System.out.println(i);
    }
}
class sub extends sup{
    int i = 6;
}
public class Work5{
    public static void main(String[] args){
        sub sb1 = new sub();
        sb1.show();
    }
}
//5
//show为父类,调用的父类的参数

抽象类

abstract class T{
    abstract void e();
}

只能被继承

image-20220109223813827

接口

image-20220109223907788

image-20220109223949392

image-20220109223957002

image-20220109224032065

image-20220109224127042

内部类

image-20220109224213593

image-20220109224229889

image-20220109224245672

image-20220109224309588

image-20220109224323622

匿名类

image-20220109224445171

class sup{    int i=5;    public sup(){//        System.out.println(i);    }    void show(){        System.out.println(i);    }}class sub extends sup{    int i = 6;    public sub(){//        System.out.println(i);    }}public class Work5{    public static void main(String[] args){        //匿名类        sub sb1 = new sub() {            public void show(){                System.out.println("AC");            }        };        sb1.show();    }}//AC

Lambda

image-20220109224514280

image-20220109224600505

image-20220109224628132

异常处理

image-20220109225708239

image-20220109225720776

image-20220109225739801

import java.io.IOException;

public class Work5{
    public static void main(String[] args){
        byte[] b;
        double i;
        while(true){
            b = new byte[6];
            try{
                System.in.read(b);
                i=Double.parseDouble((new String(b).trim()));   //trim()去掉两端多余的空格
            }
            catch(IOException e){
                System.out.println("IO error");
            }
            catch(NumberFormatException e1){
                System.out.println("number plz");
            }
        }
    }
}
/*
1
2
a
>> number plz
*/

try带资源

try (Scanner scanner = new Scanner(System.in)) {...}

资源会在try结束后自动关闭

自定义异常

class WrongInputException extends Exception {  // 自定义的类
    WrongInputException(String s) {
        super(s);
    }
}
class Input {
    void method() throws WrongInputException {
        throw new WrongInputException("Wrong input"); // 抛出自定义的类
    }
}
class TestInput {
    public static void main(String[] args){
        try {
            new Input().method();
        }
        catch(WrongInputException wie) {
            System.out.println(wie.getMessage());
        }
    } 
}

核心类

//常用类库
java.awt
java.awt.event
javax.swing
javax.swing.event
java.applet

File

image-20220109232534733

image-20220109232812807

序列化

需要先将类实现Seralizable接口

class equation implements Serializable

存入文件

try {
    ObjectOutputStream os = new ObjectOutputStream(
        new FileOutputStream("file1.data"));
    os.writeObject(equation12);
    os.close();
    System.out.println("对象已写入file1.data文件");
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

读取文件

try {
    ObjectInputStream is = new ObjectInputStream(
        new FileInputStream("file1.data"));
    ArrayList<StudentBean> list = new ArrayList<StudentBean>();
    list = (ArrayList<StudentBean>) is.readObject();
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i).toString());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

Integer

image-20220110005333207

泛型

image-20220110013314636

image-20220110013426699

image-20220110013616968

image-20220110013647161

类型擦除

如果没有指定泛型的类型,会将T设置成Object类型。

class Y<T>{
    public Y(T a){
        System.out.println(a);
    }
}

public class Work5{
    public static void main(String[] args){
        Y a = new Y(10);//T为int
        Y b = new Y("yoco");//T为String
    }
}
//10
//yoco

泛型方法

image-20220110014516113

image-20220110014533012

通配符

image-20220110014710339

image-20220110014705913

有界泛型

image-20220110014352564

image-20220110014343062

image-20220110014803041

注意

静态成员数据类型不能声明为泛型。

image-20220110014905053

String

image-20220110015119416

image-20220110015137330

image-20220110015150589

image-20220110015206843

image-20220110015235229

GUI

JFrame

image-20220109234505425

按钮

image-20220109235119322

image-20220110004922003

文本框

image-20220109235137600

布局管理器

setLayout(new BorderLayout());

BorderLayout

将容器分为五个区域:CENTER, NORTH, WEST, EAST, SOUTH

FlowLayout

image-20220109235537071

CardLayout

可使两个或更多个组件共享同一显示空间。

GridLayout

网格化。

GridLayout(int rows, int cols[, int hgap, int vgap]);

图形绘制

image-20220110004955484

实例总结

//来自许老师import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Work5 extends JFrame implements ActionListener {    boolean draw = false;    private JButton jButton1 = null;    private JButton jButton2 = null;    private JButton jButton3 = null;    private JButton jButton4 = null;    public Work5(String title) {        setTitle(title);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//        setLayout(new FlowLayout());        setLayout(new BorderLayout());        setBounds(500, 250, 300, 200);        jButton1 = new JButton("按钮1");        jButton2 = new JButton("按钮2");        jButton3 = new JButton("按钮1");        jButton4 = new JButton("按钮4");        jButton3.setText("按钮3");//        add(jButton1);//        add(jButton2);//        add(jButton3);        add(jButton1, BorderLayout.NORTH);        add(jButton2, BorderLayout.SOUTH);        add(jButton3, BorderLayout.WEST);        add(jButton4, BorderLayout.EAST);        add(new JButton("按钮5"), BorderLayout.CENTER);        add(new JButton("button6"),null);   //默认CENTER        // 传匿名内部类        jButton1.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e) {                jButton1.setEnabled(false);            }        });        // 传lambda        jButton2.addActionListener(e -> jButton2.setEnabled(false));        // 传lambda        jButton3.addActionListener(e -> {            draw = false;  // 控制是否绘图            JFrame jFrame = new JFrame("图") {                public void paint(Graphics g) {                    super.paint(g);                    g.setColor(Color.RED);                    if (draw) {  // 防止窗口在实例化时即显示图形                        g.drawOval(100, 100, 100, 100);                        g.drawRect(300, 100, 100, 100);                    }                }            };            jFrame.setBounds(200, 200, 500, 300);            jFrame.setVisible(true);            jFrame.addMouseListener(new MouseAdapter() {                public void mouseClicked(MouseEvent e) {                    draw = true;                    jFrame.repaint();                }            });        });        // 传本类        jButton4.addActionListener(this);        setVisible(true);    }    public void actionPerformed(ActionEvent e) {        jButton4.setEnabled(false);    }    public static void main(String[] args) {        Work5 guiDemo = new Work5("考试");    }}

多线程

方法

1.start(): 1.启动当前线程2.调用线程中的run方法

2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中

3.currentThread():静态方法,返回执行当前代码的线程

4.getName():获取当前线程的名字

(Thread.currentThread().getName() 获取当前线程的名字)

5.setName():设置当前线程的名字

6.yield():主动释放当前线程的执行权

7.join():在线程中插入执行另一个线程,该线程被阻塞,直到插入执行的线程完全执行完毕以后,该线程才继续执行下去

8.stop():过时方法。当执行此方法时,强制结束当前线程。

9.sleep(long millitime):线程休眠一段时间

10.isAlive():判断当前线程是否存活

image-20220106033750938

image-20220106033813963

priority

//getPriority
//MIN_PRIORITY: 1
//MAX_PRIORITY: 10
//NORM_PRIORITY: 5(默认)

互斥

// 互斥
//synchronized
public synchronized int do(){...}
public void do(){
    ...
        synchronized{
        ...
    }
    ...
}

extends Thread和implements Runnable

image-20220106034639164

Runnable容易出现脏数据,可使用synchronized避免。

//lock()   unlock()
Lock l = new ReentrantLock();//排他锁
l.lock();
...
l.unlock();

ReentrantReadWriteLock

读写锁,拥有readLock(), writeLock()

ReentrantReadWriteLock lk = new ReentrantReadWriteLock();
Lock r = lk.readLock();
Lock w = lk.writeLock();

协作(等待通知)

wait

Synchronized(ch){
    while(condition1){
        ch.wait();
    }
    while(condition2){
        ch.notify();
    }
}

await

lock.lock();
condition.await();
lock.unlock();
//不需要synchronized

线程池

image-20220106040343616

2

示例

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

class MyF extends JFrame{
    int i;
    public MyF(){
        this.setBounds(200, 200, 300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        this.setVisible(true);
    }
    public void action() throws InterruptedException {
        while (true) {
                for (i = 1; i <= 7; i++)
                    try {
                        repaint();
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName());
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
        }
    }
    public void paint(Graphics g){
        super.paint(g);
        if(i!=0)
            g.fillOval(50+i*10,50+i*10,100,100);
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        MyF w1 = new MyF();
        try {
            w1.action();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public class Work4{
    public static void main(String[] argv){
        MyThread mythread =new MyThread();
        for(int i = 0;i<3;i++){
            Thread tmp = new Thread(mythread,"win"+i);
            tmp.start();
        }
    }

}