简单不先于复杂,而是在复杂之后。
课程推荐的 jdk 下载网址为 jdk.java.net
使用命令行编译程序:javac -d bin stc*.java
使用命令行运行程序: java -cp bin 类名
java 语言标识符:字母、数字、下划线和美元符号,数字不能做首字母
java 语言中标识符区分大小写
java 语言中基本类型:byte boolean char short int long float double
java 语言中数据类型分为基本数据类型和引用类型
Java语言中基本数据类中的数值类型都是有符号的
java 语言声明常量时应使用的关键字是 final
String str = “ ”+ 23 //在23前面添加语句把23转换成String类型
int x = Integer.valueOf (“23”); int y = x + 1; //添加语句将字符串“23”转换为整型
int[] x 中变量 x 属于引用类型数据
绝大多数情况下,interface 只有借助具体的 class 实现它的功能。
java 语言中核心的概念是 class ,不能在 class 的“{”和“}”之外定义变量和函数。
顶层语法元素是指在源文件中可以直接定义的程序语言语法元素。
其他的如变量、方法只能定义在顶层语法元素之内。
class 把一组相关的数据和操作封装在其中,而 package 将一组相关的 class (和 interface、enum、record)封装在其中。
class中的内容
成员
非成员
实例成员和类成员
实例成员必须创建所属类的对象,只能通过对象的变量利用 “.”操作符加上成员名称来访问。
成员定义时添加 static 关键字,称为类成员。
类成员不需要创建对象,可以直接通过可以直接通过类名称“.”操作符加类成员来访问。
类方法只能访问类成员,不能在方法的代码中使用实例成员。
可以在 class 中定义其他的 class。(称为内部类或者接口)
非成员(构造方法)
构造方法不属于类的成员。
构造方法没有返回值,名称与类名相同。
构造方法在使用 new 关键字创建对象时使用,返回对象的引用。
如果构造方法被重载,则根据传递的实参的类型和数量确定实际执行时调用的构造方法。
构造方法重载是指在同一个类中定义了多个构造方法,它们的方法名相同但参数列表不同
只有在源代码中没有定义构造方法的情况下,编译器才会创建一个无参数的构造方法,这个无参构造方法称为默认构造方法(无参构造方法不一定是默认构造方法)
构造方法也和成员方法一样,可以被重载。
可以在定义构造方法时,使用 this 关键字调用其他重载的构造方法,必须是方法体中第一句。
this关键字表示对象自身,通常用在方法形参与成员变量同名时,也可以在其他为了区分二者的情况下使用。
this 关键字不能用于 static 方法内
包将一组相关的 class 、interface组织在一起,主要起到区分命名空间的作用,不同的包中可以各自定义自己类,即使相同的类名称,也不会造成命名冲突。
包名由一个或多个子包名用“.”连接起来组成,每个子包名必须符合 Java 语言的标识符命名规则。
标识符由字母、数字、下划线(_)和美元符号($)组成。,第一个字符不能是数字。
包名一般使用小写字母,且采用逆域名命名规则。
如果要将源文件中的所有类都添加到某个包中,必须在源文件中添加 package语句,例如 package pack.age.name
包声明语句必须是源文件中第一行非注释语句。
没有包声明语句的源文件,其中的类属于默认包。
如果要使用包中的若干类,则必须在源文件中添加 import 语句:
import pack.age.name.*;
import pack.age.name.ClassName;
import static Math.PI;
一个类成为主类必须同时具备两个条件:
public static void main(String[] args)
方法一个类如果位于某个包中,则它的完整类名 = 包名+类名,如:xsyu.java2023.demo.Hello
运行时必须指定主类的完整名称
一个 class 定义必备的三个条件是:class 关键字、类名、{}
Java 源文件的名称必须和其中的 public 类的名称相同。
对于一个属于非默认包的类,它编译后的 class 文件必须保存在和包名对应的目录结构下。
假设 Hello.java 保存在 当前目录的 src 子目录下,编译命令为:javac -d bin src\*.java
这条命令把位于当前目录的 src 子目录中所有 java 源文件都编译成 .class 文件,保存在当前目录的 bin 目录下,可以看到 bin 目录下自动根据包名建立好了嵌套好的文件夹结构,Hello.class 保存在最底层的 demo 目录下。
要运行上面编译好的 Hello.class 程序,运行命令为java -cp bin xsyu.java2023.demo.Hello
interface 中通常只定义两类内容:
实现接口
class ClassName implements[interface列表]{
//······
}
一个 class 可以实现多个 interface
所谓实现(implements)就是把 interface 中定义的抽象方法具体化,定义出这些方法的具体代码
如果一个类只实现了部分 interface 中定义的抽象方法具体化,则该类必须被定义为 abstrac class .未实现的方法无需在 abstrac class 中再声明。
一个非抽象类必须实现 implemnts 列表中的所有接口的所有方法。
可以声明 interface 类型的变量,把实现了同一 interface 的 class 对象赋值给对应 interface 类型的变量。但不可以用 new 关键字创建 interface 类型的变量,因为其中有未明确定义的抽象方法。
interface MyInterface {
void myMethod();
}
class MyClass implements MyInterface {
public void myMethod() {
System.out.println("Implementation of myMethod");
}
}
public class Main {
public static void main(String[] args) {
// 声明接口类型的变量
MyInterface myObject;
// 将实现了相同接口的类对象赋值给变量
myObject = new MyClass();
// 调用接口方法
myObject.myMethod(); // 输出:Implementation of myMethod
}
}
抽象方法:abstract Type method([参数列表]); 添加了 abstract 关键字装饰,但没有定义方法体的方法。
抽象类中可以包含 abstract 方法 ,也可以不包含 abstract 方法。
如果一个 class 中定义了 abstract 方法,则这个 class 必须被定义为 abstract class
抽象类中可以定义构造方法
和 interface 一样,可以声明某个 abstract class 类型的变量,把某个继承了这个 abstract class 的具体类对象赋值给对应 abstract class 类型的变量。但不可以使用 new 关键字创建 abstract class 类型的变量
public: 所有代码都可以访问
protected: 除同一个 package 中的其他类可以访问外,即使属于不同包的子类也可以访问。
默认(无修饰符): 默认只有同一个 package 中的其他类可以访问
private: 只有类自身的成员方法和构造方法可以访问
通常情况下,成员变量都定义为 private ,然后根据需要定义读取或者修改成员变量的方法。
成员方法也只在明确需要外界访问时,定义成 public 等相对宽松的访问范围
class ClassName extends SuperClass{
//
}
interface InterfaceName extends /*[interface列表]*/{
//
}
在 java 语言中,class 是单继承,extends 关键字后只能有一个类名,即只能有一个直接父类;interface 是单继承,extends 关键字后可以有多个 interface 名称。
如果一个类定义时没有使用 extends 关键字,则它的超类是 Object 类
Object
类是Java中所有类的根类,它定义了一些通用的方法,如toString()
、equals()
、hashCode()
等。因此,所有的Java类都最终是Object
类的子类,直接或间接地。
子类的代码中,可以直接访问所有符合访问控制规则的超类中的成员。
子类的构造方法总会调用超类的构造方法。如果在子类的构造方法中,没有调用超类构造方法的语句,则编译器会插入调用超类无参构造方法的语句。
子类中明确调用超类构造方法时,使用 super 关键字。
需要时,子类中可以使用 super 关键字访问超类的成员变量或者成员方法。
可以把子类对象赋值给超类类型的变量。(向上转型)
可以使用子类类型的变量访问超类中符合访问规则的成员
如果把子类对象赋值给超类类型变量,则不能使用超类类型变量访问只在子类中定义的成员’
不属于和超类同一包中的类,无法通过子类变量来访问 protected 成员。
protected
成员。protected
的成员。protected
成员。final class ClassName {…},则该类不能被继承
重载:同一个类中多个方法具有相同的方法名,参数列表不同
覆盖:指子类中重新定义超类中已有的一个或者多个方法/以及实现接口中的方法。
public
final
关键字,则该方法不能被覆盖。隐藏:子类中定义了与超类中同名的成员变量,默认情况下,这个变量名指代子类的成员变量,称该超类变量被隐藏。
覆盖所产生的多态效应,特别的是指在变量为某超类类型,而实际对象为其子类对象时,调用被覆盖方法,执行实际对应子类对象方法。
Object 类是所有类的超类,因为所有类都是直接或间接继承自它。
Object 类中重点关注的方法:
控制台
输出:
System.out.println//打印输出并换行
System.out.printf//格式化输出
System.out.print//打印输出不换行
输入:
Scanner input = new Scanner(System.in);
//intput.nextXXX
String userInput = input.nextLine(); // 读取用户输入的一行字符串
int userNumber = input.nextInt(); // 读取用户输入的整数
input.close()
Files
//Path path = Path.of(<filepath>);
String content = "Hello,wotld!";
//Files.writeString(path,content);
//Files.writeString(path,content,StandardOpenOption.APPEND);
//Files.writeString(path,content,Charset.forName("UTF-8"),StandardOpenOption.APPEND);
PrintWriter
PrintWriter out = new PrintWriter("filename.txt","UTF-8");//Charset.forName("UTF-8")
//out.println
//out.printf
//out.print
//write,write(String s)
out.close();
异常:在程序运行中发生的,导致程序不能正常执行的事件对象 Error 类和Exception类都继承自Throwable类,RuntimeException类是Exception类的子类
三种异常
抛出异常的关键字:throw ExceptionObj
异常处理原则:捕获或者声明
对于编译时检查,必须编写应对可能抛出的异常。有两种方式:
第一种捕获异常的句式(try-catch-[finally]
):
try{
......
......
}catch(ExceptionType1 ex){
......
.......
}catch((ExceptionType2 ex){
......
........
}catch((ExceptionTypeN ex){
.....
....
}catch(Exception1|Exception2|ExceptionN ex){
...
.....
}
//[如果有类似文件等资源需要释放,添加finally子句
finally{
//finally块中的代码无论是否发生异常,都会执行。
//资源释放代码
}
第二种捕获异常句式(try-with-resources)
//try-with-resources 句式中,try()之间可以创建多个I/O对象(比如,有时同时需要读、写文件),中间用“;”
try(StreamType1 objRef1 = new StreamType1(...);
StreamType2 objRef2 = new StreamType2(....)){
}catch(ExceptionType1 ex){
......
.......
}catch((ExceptionType2 ex){
......
........
}catch((ExceptionTypeN ex){
.....
....
}catch(Exception1|Exception2|ExceptionN ex){
...
.....
}
//[如果有其他非I/O流资源需要释放,添加finally子句
finally{
//finally块中的代码无论是否发生异常,都会执行。
//资源释放代码
}
可以通过继承 Exception 类创建自定义异常,使用 throw 关键字抛出
catch 语句是按照编码顺序进行匹配,所以,多个catch子句包含子类和父类异常时,子类catch语句应在前
finally子句总是被执行,所以应在finally子句中释放资源
try块中定义的变量在catch子句中无法访问
子类覆盖方法时,不能添加异常
如果自定义的方法中,有代码可能抛出 checked 异常,如果没有使用 try-catch 语句捕获,方法定义时必须使用 throws 关键字声明这些 checked 异常 vod method() throws exception1,exception2(...)
调用可能抛出异常的方法可以捕获,或者再次声明throws
进程:内存等计算资源分配单位(文件句柄)
线程:CPU 调度单位
并发: 并发是指多个任务在一段时间内同时执行,可能是交替执行,但在宏观上看起来是同时的。在并发模型中,多个任务可以在同一个时间段内启动、执行和完成。
并行:并行是指多个任务在同一时刻同时执行。在并行计算中,多个处理器或核心可以同时执行多个任务,提高计算速度。
并行是并发的一种特例
1. 继承 Thread 类
class Task extends Thread{
public void run(){
//
}
}
Thread taskRef = new Task();
taskRef.start();
2. 实现 Runnable 接口
class Task implements Runnable{
public void run(){
//
}
}
Thread taskRef = new Thread(new Task());
taskRef.start();
public class HelloWorld{
public static void main(String[] args){
system.out.println("Hello world!");
}
}
import javax.swing.*;
public class EmptyWindow extends JFrame{
public EmptyWindow(){
setSize(1024,768);//设置窗口大小
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args){
SwingUtilies.invokeLater(
()->{
JFrame frame = new EmptyWindow();
frame.setVisible(true);//显示窗口
}
);
}
}
import javax.swing.*;
public class AddComponentDemo extends JFrame{
public AddComponentDemo(){
setSize(800,600);//设置窗口大小
//确保点击窗口关闭按钮时,程序能正常退出
setDefaultCloseOperation(EXIT_ON_CLOSE);
initComponents();
}
private void initComponents(){
inputField = new JTextField(); //创建输入框
//输入框左上角坐标(500,500),宽度180,高度25
inputField.setBounds(500,500,180,25);
bt = new Jbutton("按钮"); //创建按钮
//按钮左上角坐标(700,500),宽度60,高度25
bt.setBounds(700,500,60,25);
setLayout(null); //为了使得 setBound 能够正常工作,需要设置布局管理器为 null
add(bt); //添加按钮组件
add(inputField); //添加文本输入框组件
}
public static void main(String[] args){
SwingUtilities.invokeLater(
()->{
JFrame frame = new AddComponentDemo();
frame.setVisible(true);//显示窗口
}
);
}
private JButton bt;
private JTextField inputField;
}
import javax.swing.*;
public class AddComponentDemo extends JFrame {
private JButton bt;
private JTextField inputField;
public AddComponentDemo() {
setSize(800, 600); // 设置窗口大小
setDefaultCloseOperation(EXIT_ON_CLOSE); // 设置点击窗口关闭按钮时程序能正常退出
initComponents(); // 初始化组件
}
private void initComponents() {
inputField = new JTextField(); // 创建文本输入框
// 设置输入框左上角坐标(500,500),宽度180,高度25
inputField.setBounds(500, 500, 180, 25);
bt = new JButton("按钮"); // 创建按钮
// 设置按钮左上角坐标(700,500),宽度60,高度25
bt.setBounds(700, 500, 60, 25);
setLayout(null); // 为了使得 setBounds 能够正常工作,需要设置布局管理器为 null
add(bt); // 添加按钮组件
add(inputField); // 添加文本输入框组件
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
() -> {
JFrame frame = new AddComponentDemo();
frame.setVisible(true); // 显示窗口
}
);
}
}
AddComponentDemo
类: 继承自 JFrame
类,表示一个窗口。
initComponents
方法: 初始化窗口中的组件,包括文本输入框和按钮。通过 setBounds
方法设置组件的位置和大小,通过 setLayout(null)
禁用布局管理器,使得 setBounds
能够正常工作。
main
方法: 使用 SwingUtilities.invokeLater
来确保窗口在事件分派线程上创建,避免多线程问题。创建 AddComponentDemo
的实例并显示窗口。
// 添加按钮组件
add(inputField); // 添加文本输入框组件
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
() -> {
JFrame frame = new AddComponentDemo();
frame.setVisible(true); // 显示窗口
}
);
}
}
1. **`AddComponentDemo` 类:** 继承自 `JFrame` 类,表示一个窗口。
2. **`initComponents` 方法:** 初始化窗口中的组件,包括文本输入框和按钮。通过 `setBounds` 方法设置组件的位置和大小,通过 `setLayout(null)` 禁用布局管理器,使得 `setBounds` 能够正常工作。
3. **`main` 方法:** 使用 `SwingUtilities.invokeLater` 来确保窗口在事件分派线程上创建,避免多线程问题。创建 `AddComponentDemo` 的实例并显示窗口。
4. **`bt` 和 `inputField`:** 分别表示按钮和文本输入框的实例变量,可以在类的其他方法中使用。