vscode编码不匹配,源文件用UTF-8,但JDK默认使用GBK编译(Windows下常见),所以报”编码 GBK 的不可映射字符”,可以编译时在PowerShell/cmd编译时加参数:
javac -encoding UTF-8 Filename.java
java Filename

Scanner类简介:
1、使用前导包入:import java.util.Scanner;
2、构造Scanner类对象,它附属于标准输入流System.in。
Scanner sc =new Scanner(System.in);
3、常用的next()方法系列(Scanner不能获取char字符类型):
nextInt():输入整数
nextLine():输入字符串
nextDouble():输入双精度数
next():输入字符串(以空格作为分隔符)

==比较的是两个对象的内存地址,而变量被创建的时候相当于在内存中开辟空间,内容一致但内存地址不一致,判断不相等。
在Java中判断两个字符串是否相等要使用equals方法——str1.equals(str2),如果str1等于str2则返回true。

arr.length表示数组长度

println()输出末尾携带换行符,print()不携带。

数组int[] scores={1,2,3}大小在创建时就固定了,括号里不填是让编译器自己判断所占空间大小。

八种数据类型(字符串不属于基本数据类型)

  1. byte b=127(范围-128~127)
  2. short s(范围-32768~32767)
  3. int i(范围-2^32~2^31-1)
  4. long l=1l(范围-2^63~2^63-1,数字后要加l)
  5. float f=1.23f(数字后要加f)
  6. double d=1.23(不加)
  7. boolean boo=true
  8. char c=’好’(单引号)

表数范围小的可以向表数范围大的进行自动类型转换

a==b return true/false,而不return 0/1

a&&b(与:都为true,return true)
a||b(或:有一个true,return true)
!a(非:true return false)
a^b(异或:只有一个true,return true)

function?ans1(true):ans2(false) 三元运算符

运算符优先级别排序由高向低分别是:()、!、算术运算符、关系运算符、逻辑运算符、赋值运算符

switch(input){},python的switch input :才是冒号!

一个程序可以由多个文件组成,每个文件可以定义多个类,每个类包含方法和变量,必有一个主方法main()。main()方法必须有参数 String[] args,没有参数会导致程序无法运行。
如果程序中有public类,文件名必须与public类的类名完全相同,扩展名为.java。 组成程序的多个类中,必须有且只有一个主类(包含public static void main(String[] args)方法的类)。不允许在一个.java文件中声明多个public类。

标识符可以包含字母、数字、下划线和美元符号,不能包含#号,空格,连字符(-),不能以数字,等号(=)开头。

Java程序编译后生成的是面向JVM的字节码文件,扩展名为.class,字节码文件可以在任何安装JVM的平台上运行,体现了Java的”一次编译,到处运行”特性。

按位或(bitwise OR)运算。|(按位或)有1则1,&(按位与)全1则1,^(按位异或)不同则1。位数不够自补全0。

Java语言使用的是Unicode字符集,Unicode字符集中,每个字符在内存中占16位(2字节)。
Java先编译为字节码,然后由JVM解释执行,是编译解释型语言。str.length()。
不能直接将字符串赋值给char数组,应该用 char[] str = “”.toCharArray();
运行字节码文件时,使用java命令不加.class扩展名。机器不能直接识别字节码文件,它要经过JVM中的解释器边解释边执行。

Java只支持单继承(一个类只能继承一个父类),通过接口(interface) 实现多继承的效果(一个类可以实现多个接口)。支持分布式的网络应用,可透明地访问网络上的其他对象。支持多线程编程。与平台无关、可移植性好。

在运行字节码文件时,使用java命令,一定要给出字节码文件的扩展名.class

数组:t.length (属性,没有括号)
String:t.length() (方法,有括号)
集合:t.size() (方法,有括号)

类名 对象名 = new 类名();对象名.属性名 = 值;对象名.方法名();对象名.属性名
Java规定构造方法名必须与类名相同。构造方法没有返回值(return NULL),且不用void关键字声明(有void就变成普通方法了)。构造方法可以重载,一个类可以有多个参数不同的构造方法。构造方法只能用new关键字来调用创建对象。
Java 有自动垃圾回收机制(GC),负责回收不再使用的对象所占用的内存。
new 运算符返回的是对象的引用(地址),而不是对象本身。创建对象时,系统会自动调用匹配的构造方法进行初始化。实例方法中可以引用类变量(静态变量),因为类变量属于类,可以被所有实例方法访问。对象赋值是引用传递,两个变量指向同一个对象,因此具有相同的引用值。
在 Java 中,类中声明的方法必须定义在类体内,不能在类体外定义。类是对象的模板,也是一种引用数据类型。

如果没有写任何构造函数,编译器会自动生成一个无参构造函数;如果写了一个有参数的构造函数,编译器不会再帮你生成无参构造函数;如果你既想支持自定义构造、又想支持 Class obj写法,就要手动写一个无参构造函数。
保证类可被默认实例化,允许框架/反射机制实例化对象,支持继承体系中父类默认调用。

@Override是注解(Annotation),意思是这个方法重写(override)了父类中的方法。不写@Override代码能运行,但编译器不会检查提醒方法签名写错、没有真正覆写父类方法。
Override(重写)表示在类中定义一个和父类方法”同名、同参数、同返回类型”的方法,但内部实现不同,用来覆盖父类版本。

Java中所有类都默认继承自Object 类。

this是一个关键字,用来表示当前对象(即当前实例)。每当用new创建一个对象,系统就会在内存中分配一个新的实例,当这个对象在调用它自己的方法(比如c1.add(…))时,Java 会自动传递一个”指向当前对象”的引用,这个引用就是 this。

Java中,如果类里的属性(或方法)不显式声明访问修饰符(public、protected、private)那它的访问权限是:默认(default)访问级别,也称为包访问权限(package-private).

关键字final修饰变量表示一旦赋值,就不能再重新赋值修改。

修饰方法表示禁止被子类重写。
修饰类表示不能被继承。
public final int

例变量(类成员变量)自动赋初值0,局部变量无默认值,必须显式初始化。

子类虽然继承了父类的所有成员,但私有成员(private)无法直接访问。抽象类可以有构造方法,用于子类初始化时调用。只是不能被实例化。构造方法可以重载(参数不同),但不能继承。Java 只支持单继承(一个类只有一个父类),但可以实现多个接口。Java 不支持运算符重载(除了 + 可以连接字符串)。仅仅改变返回类型不构成重载,参数列表必须不同。一个类可以实现多个接口,但只能继承一个类。访问权限是由修饰符决定的,不会因为继承而改变。父类不能包含子类,只是子类继承父类。protected = 同包 + 其他包的子类 可访问。没有写 public、protected、private 的类,只能被同包访问。public 表示对整个工程可见。构造方法只能给实例成员变量赋初值。实现接口的类不能是抽象类。

Java核心包中,提供编程应用的基本类的包是java.lang,paint()方法使用Graphics类型的参数,常量全部大写,一个.java文件中定义多个类时,只允许其中声明一个public类。Java支持分布式的网络应用,可透明地访问网络上的其他对象。/**…*/注释方法能够支持javadoc命令,Java源程序不是编译型的,而是编译解释型的。机器不能直接识别字节码文件,它要经过JVM中的解释器边解释边执行。

当子类创建对象时,要先调用父类构造器,不写super(…)时默认会调用super()(父类的无参构造),若父类没有无参构造,必须手动写super(…)。
当子类重写了父类方法,但还想用父类原来的方法时,可以用 super.xxx()。
this → 指当前类对象,super → 指父类对象

数组里每个元素的构造参数确实不同,但这是正常的,因为它们是不同类型的对象。每个构造器接收的参数数量和意义不同,因为类本来就不一样。数组只关心类型是否兼容(有没有继承关系),不管参数一样不一样。

  • 普通的for循环遍历
    for (int i = 0; i < staff.length; i++) {
    Employee e = staff[i];
    }
  • 简化的迭代器遍历
    for (Employee e : staff) {
    }

String和StringBuffer 的区别主要集中在 是否可变、线程安全、性能用途 这三个点。
String一旦创建内容就不能改,修改时会生成新对象。StringBuffer直接操作同一块内存,不重新建对象。
String不可变天然线程安全,StringBuffer内部方法有synchronized(线程安全)。

String类的compareTo()用来比较字符串大小的方法。质上是按字符的Unicode编码(包括ASCII范围)逐个比较来决定大小。ASCII 是 Unicode 的子集。

1
2
3
String类自带的split()方法," "连续空格会被当成空字符串拆开,而"\\s+"把多个空白看成一个分隔符。
正则表达式中\s匹配任意空白字符(包括空格' ',Tab \t,换行 \n,回车 \r)。+的正则含义是一个或多个前面的字符,a+表示一个或多个 a,\d+表示一个或多个数字。
因为Java字符串有转义字符,想在字符串里写\,必须写\\,所以正则里的\s+实际要写"\\s+"。
1
2
3
4
// 字符串二进制转换为十进制,不必使用幂函数
for (int i = 0; i < str.length(); i++) {
ans = ans * 2 + (str.charAt(i) - '0');
}

String对象一旦被创建,其内容就不能被改变。在一个循环中反复进行字符串拼接,就会产生大量中间态的 String 对象,效率非常低。
StringBuffer对象是可变的。它的内部是可变的字符数组。

StringBuffer不能直接赋值给String,return buffer.toString()来解决。

charAt(int index) - 获取指定索引位置的字符
length() - 获取字符串长度
indexOf(String str) - 查找指定子串第一次出现的索引位置
equalsIgnoreCase(String another) - 比较两个字符串是否相等,忽略大小写差异
replace(char oldChar, char newChar) 将字符串中所有的旧字符替换为新字符
startsWith(String prefix) 检查字符串是否以指定的前缀开头
endsWith(String suffix) 检查字符串是否以指定的后缀结尾
toUpperCase() 将字符串中的所有字符转换为大写
toLowerCase() - 将字符串中的所有字符转换为小写
substring(int beginIndex) 从指定索引开始截取字符串到末尾
trim() - 去除字符串开头和结尾的所有空白字符

抽象类(Abstract Class)不能被实例化(不能直接new),主要作为其他类的父类(基类),可以包含抽象方法和普通方法,子类必须实现所有的抽象方法(除非子类也是抽象类)

抽象方法 (Abstract Method)只有方法声明,没有方法实现(没有{}方法体),以分号结束,必须在抽象类中声明,子类必须重写所有的抽象方法。抽象方法必须加public和返回类型void,如public abstract void printMsg();

Java只支持类的单继承,但支持接口的多继承。多继承会带来所谓的 “菱形继承问题” (Diamond Problem)。如果多个接口中存在相同默认方法,子类必须显式重写以解决冲突。

interface(接口)是一种 “行为规范” 或 “契约”,定义了一组方法(通常没有具体实现),规定了一个类“应该做什么”,但不关心怎么做。implements 关键字表示类去实现接口。一旦实现接口,类就必须实现接口中定义的所有方法。

通过接口类型的引用,指向了一个具体实现类的实例。

接口默认不能有实现,成员变量 默认是 public static final(常量),不能有构造方法,类可以实现多个接口,定义”能做什么”的能力。
抽象类可以有具体方法和抽象方法,可以是普通实例变量,可以有构造方法,类只能继承一个抽象类,定义”是什么”的继承关系。

public abstract class A {
public abstract void function(); // 抽象方法
}

public class B extends A {
@Override
public void function() {
;
}
}

public interface A {
void function();
}

public class B implements A {
@Override
public void function() {
;
}
}

throw:语句,用在方法内部
主动抛出异常对象,用在方法体内部,后面必须跟一个异常对象(new 出来的),执行到 throw 时方法会立即结束并抛异常
代码运行到这里时,我立即抛出这个异常对象。
进入方法


执行代码逻辑

├── 条件满足?
│ │
│ ├─ 否 → 继续执行后续代码
│ │
│ └─ 是
│ │
│ ▼
│ 执行 throw
│ │
│ ▼
│ 方法立即结束
│ │
│ ▼
└────→ 异常抛给调用者

throws:方法声明的一部分,把异常往外“抛给调用者处理”
写在方法名后面,后面跟的是异常类型(不是对象),告诉调用者:这个方法可能抛这些异常,调用者需要负责处理或继续上抛
这个方法可能产生某类异常,调用者自己负责处理。
调用方法 A() ───────────────┐

方法 A() 声明了 throws XxxxException


方法 A 内部可能产生异常?

┌────────────┴─────────────┐
▼ ▼
否(未产生异常) 是(产生了异常)
│ │
▼ ▼
正常执行后续逻辑 异常被抛出
│ │
▼ ▼
方法 A 正常返回 调用者必须 try/catch 或继续 throws

try / catch 是“异常处理机制”
运行 try 里的代码 → 如果发生异常 → 自动跳到 catch 执行。
出现运行时错误(如除 0),程序不会崩,而是进入 catch
finally 的意思是: 无论 try 或 catch 是否执行、是否抛异常、是否 return,finally 都一定会执行。它代表 最终都会执行的代码块。
finally 的内容 确实可以 写在:try 的末尾或 catch 的末尾但这样做会产生 重复代码。因此,Java 设计了 finally,用于把 无论如何都要执行的代码 从 try/catch 中抽出来,避免重复。

返回类型为 void 的方法 中:return; 是合法的
所有的异常类皆继承java.lang.Throwable类
Object
|
Throwable
/
Exception Error