Java基础
Java 基础
基本概念
JDK:开发 JAVA 的工具包,包括 Javac(编译工具),运行环境 JRE、其他工具。
JRE:Java 运行环境,包括 Java 虚拟机 JVM 和 Java 核心类库。
javac:将.java 文件编译成.class 字节码文件。
JVM:Java 虚拟机,负责执行.class 字节码文件,字节码转不同平台机器码运行。
HelloWorld
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}数据类型
基本数据类型
最基本的数据类型和对应的包装类:
整型:
- byte Byte 1Byte -128~127
- short Short 2Byte -215~215-1
- int Integer 4Byte -231~231-1
- long Long 8Byte -263~263-1
浮点型:
- float Float 4Byte -2127~2127-1
- double Double 8Byte -2127~2127-1
布尔型:
- boolean Boolean 1Bit 0/1
字符型:
- char Character 2Byte 0~65535
包装类什么时候用:
- 泛型必须用包装类
- POJO 数据库实体对象字段
数据转换
放大转换(自动执行)
byte -> short -> char -> int -> long -> float -> double
double+float+int 会选最大的缩小转换(需要强制)
double -> float -> long -> int -> char -> short -> byte
引用数据类型
String
只有 String(开头大写),没有 string(开头小写)
没有 s[0],而是 s.charAt(0)
String s = " Hello World ";
s.length(); // 获取长度: 13
s.isEmpty(); // 是否为空字符串: false
s.trim(); // 去除首尾空格: "Hello World"
s.charAt(1); // 获取指定索引字符: 'H'
s.substring(1, 6); // 截取字符串: "Hello"
s.indexOf("o"); // 查找子串首次出现位置: 5
s.lastIndexOf("o"); // 查找子串最后一次出现位置: 8
s.replace("l", "x"); // 替换字符: " Hexxo Worxd "
s.split(" "); // 分割字符串,返回数组
s.join("-"); // 使用"-"连接字符串: "Hello-World"
s.equals("hello"); // 比较内容是否相等
s.equalsIgnoreCase("..."); // 忽略大小写比较
s.contains("Hello"); // 是否包含子串
s.toLowerCase(); // 转小写
s.toUpperCase(); // 转大写
s.startsWith("Hello"); // 是否以"Hello"开头
s.endsWith("World"); // 是否以"World"结尾字符串拼接:
System.out.println("Hello" + " " + "World"); //Hello World
System.out.println("Hello" + 1); //Hello1
System.out.println("Hello" + 1 + 2); //Hello12
System.out.println(1 + 2 + "Hello"); //3Hello转义字符:
\n 换行,\t 制表,\r 回车(回到行首),\b 退格,\f 换页
System.out.println("Hello\nWorld"); //Hello
//World
System.out.println("Hello\tWorld"); //Hello World
System.out.println("Hello\rWorld"); //World
System.out.println("Hello\bWorld"); //HellWorld
System.out.println("Hello\fWorld"); //Hello
//World如果字符串需要多次添加,可以使用 stringBuilderString,StringBuilder,StringBuffer
数组
//初始化
int[] arr;
int[] arr = {1,2,3};
int[] arr = new int[3];
int[][] arr = new int[3][3];
//遍历
for(int i = 0;i<arr.length;i++){};
for(int a: arr){};//增强for循环
//常用方法
arr.length; //长度
Arrays.sort(arr);//排序
Arrays.toString(arr);//转字符串基本语法
运算符
| 算数运算符 | 说明 | 示例 |
|---|---|---|
+ | 加法 | a + b |
- | 减法 | a - b |
* | 乘法 | a * b |
/ | 除法 | a / b |
% | 取模(求余) | a % b |
| 关系运算符 | 说明 | 示例 |
|---|---|---|
== | 等于 | a == b |
!= | 不等于 | a != b |
> | 大于 | a > b |
< | 小于 | a < b |
>= | 大于等于 | a >= b |
<= | 小于等于 | a <= b |
| 逻辑运算符 | 说明 | 示例 |
|---|---|---|
&& | 逻辑与(短路) | a && b |
|| | 逻辑或(短路) | a || b |
! | 逻辑非 | !a |
| 位运算符 | 说明 | 示例 |
|---|---|---|
& | 按位与 | a & b |
| | 按位或 | a | b |
^ | 按位异或 | a ^ b |
~ | 按位取反 | ~a |
<< | 左移 | a << 2 |
>> | 右移(带符号) | a >> 2 |
>>> | 无符号右移 | a >>> 2 |
| 赋值运算符 | 说明 | 等价形式 |
|---|---|---|
= | 赋值 | a = b |
+= | 加后赋值 | a = a + b |
-= | 减后赋值 | a = a - b |
*= | 乘后赋值 | a = a * b |
/= | 除后赋值 | a = a / b |
%= | 取模后赋值 | a = a % b |
&= | 按位与后赋值 | a = a & b |
|= | 按位或后赋值 | a = a | b |
^= | 按位异或后赋值 | a = a ^ b |
<<= | 左移后赋值 | a = a << b |
>>= | 右移后赋值 | a = a >> b |
>>>= | 无符号右移后赋值 | a = a >>> b |
| 其他运算符 | 说明 | 示例 |
|---|---|---|
? : | 三元运算符 | condition ? value1 : value2 |
提示
没有次方运算符不是^,而是Math.pow(a,b)
如果使用2 的 n 次方,可以使用位移1<<n
循环
普通 for 循环:
for (int i = 0; i < 10; i++) {
System.out.println(i);
}增强 for 循环:
for (int i : array) {
System.out.println(i);
}while 循环:
while(i<10){
System.out.println(i);
i++;
}do-while 循环:
do {
System.out.println(i);
i++;
} while (i < 10);条件分支
if 条件:
if(score>=90){
System.out.println("A");
}else if(score>=80){
System.out.println("B");
}else{
System.out.println("C");
}switch 条件:
switch (score) {
case 90:
System.out.println("A");
break;
case 80:
System.out.println("B");
break;
default:
System.out.println("C");
break;
}重要
- switch 条件中的 case 值必须是常量,不能是变量
- break 用于结束 switch 语句
- default 用于处理所有未匹配的情况
:::
面向对象 (OOP)
类与成员
- 属性(成员变量):描述类的特征,用变量表示。
- 方法(成员函数):描述类的行为,用函数表示。
- 构造方法:创建对象时自动调用,用于初始化。名称与类名一致,无返回值。
访问修饰符
| 修饰符 | 同一类 | 同一包 | 子类 (不同包) | 其他包 |
|---|---|---|---|---|
| private | ✔️ | ❌ | ❌ | ❌ |
| (default) | ✔️ | ✔️ | ❌ | ❌ |
| protected | ✔️ | ✔️ | ✔️ | ❌ |
| public | ✔️ | ✔️ | ✔️ | ✔️ |
其他修饰符
- static:静态,属于类而非实例。可通过类名直接访问,不能直接访问实例成员。
- final:最终。修饰变量为常量(不可修改),修饰方法不可重写,修饰类不可继承。
面向对象三大特性
1. 封装 (Encapsulation)
将类的内部实现细节隐藏,通过私有化属性(private)并提供公共的 getter/setter 方法来控制访问,提高安全性和可维护性。
2. 继承 (Inheritance)
子类(extends)继承父类的属性和方法,实现代码复用和扩展。
- super:指向父类对象(引用父类属性、调用父类方法或构造器)。
- @Override:标注方法重写,确保子类正确覆盖父类逻辑。
- 限制:
final类不可被继承,final方法不可被重写。
3. 多态 (Polymorphism)
定义:同一个行为在不同对象上表现出不同的形式。核心表现为:父类引用指向子类对象。
前提条件:
- 子类继承父类
- 子类重写父类方法
- 父类引用指向子类对象:
Animal a = new Dog();
向上/向下转型:
- 向上转型:系统自动完成,转型后只能调用父类中定义的方法。
- 向下转型:需显式强制转换,建议结合
instanceof检查及安全转换。
if (animalRef instanceof Dog) {
Dog dog = (Dog) animalRef;
dog.fetch(); // 转型后可调用子类特有方法
}示例代码:
class Animal {
void sound() { System.out.println("Animal makes a sound"); }
}
class Dog extends Animal {
@Override
void sound() { System.out.println("Dog barks"); }
void fetch() { System.out.println("Dog fetches ball"); }
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // 多态
myDog.sound(); // 输出: Dog barks
}
}构造方法执行顺序:
- 父类构造方法
- 子类构造方法
代码示例:
class Parent {
Parent() {
System.out.println("1. 父类构造器被调用");
test(); // [!code warning] 陷阱隐患
}
void test() { System.out.println("父类 test"); }
}
class Child extends Parent {
int num = 10; // 子类显式初始化赋值
Child() {
System.out.println("2. 子类构造器被调用,num = " + num);
}
@Override
void test() {
System.out.println("子类重写 test,num = " + num);
}
}
public class Test {
public static void main(String[] args) {
new Child();
}
}
// 执行结果:
// 1. 父类构造器被调用
// 子类重写 test,num = 0 <-- 注意:此时 num 尚未被赋值为 10
// 2. 子类构造器被调用,num = 10[!IMPORTANT] > 多态陷阱:如上例所示,如果在父类构造方法中调用了被子类重写的方法,实际执行的是子类的方法。但此时子类的成员变量(如
num)尚未执行显式赋值初始化,因此处于默认值(0/null),这可能导致非预期的空指针或逻辑错误。
抽象类
为子类提供一个通用的模版和框架,定义一些通用的逻辑或规范,同时允许子类根据需要实现具体功能。
1、抽象类不能被实例化。
2、抽象类应该至少有一个抽象方法,否则它没有任何意义。
3、抽象类中的抽象方法没有方法体。
4、抽象类的子类必须给出父类中的抽象方法的具体实现,除非该子类也是抽象类。
// 抽象类 Animal
abstract class Animal {
protected String name;
// 构造方法
public Animal(String name) {
this.name = name;
}
// 抽象方法:子类必须实现
public abstract void sound();
// 普通方法:所有子类共享
public void sleep() {
System.out.println(name + " is sleeping.");
}
}
// 子类 Dog 继承自 Animal
class Dog extends Animal {
// 构造方法
public Dog(String name) {
super(name);
}
// 实现抽象方法
@Override
public void sound() {
System.out.println(name + " says: Woof!");
}
}
// 子类 Cat 继承自 Animal
class Cat extends Animal {
// 构造方法
public Cat(String name) {
super(name);
}
// 实现抽象方法
@Override
public void sound() {
System.out.println(name + " says: Meow!");
}
}
// 测试类 Main
public class Main {
public static void main(String[] args) {
// 创建 Dog 对象
Animal dog = new Dog("Buddy");
dog.sound(); // 输出:Buddy says: Woof!
dog.sleep(); // 输出:Buddy is sleeping.
System.out.println();
// 创建 Cat 对象
Animal cat = new Cat("Kitty");
cat.sound(); // 输出:Kitty says: Meow!
cat.sleep(); // 输出:Kitty is sleeping.
}
}二、接口
定义一组行为规范
接口通过抽象方法定义了一组行为规范,强制实现类实现这些方法
一个类可以实现多个接口,从而表现出多种行为
字段默认是
public static final,用于定义全局常量表示 can do what
如果一个类实现的多个接口中有同名的默认方法,需要手动解决冲突
// 定义接口 Flyable interface Flyable { // 静态常量(全局常量) int MAX_SPEED = 1000; // 默认是 public static final // 抽象方法:所有实现类必须实现 void fly(); // 默认方法(Java 8 引入):提供默认实现 default void land() { System.out.println("Landing..."); } // 静态方法(Java 8 引入):通过接口名调用 static void info() { System.out.println("This is the Flyable interface."); } } // 实现类 Bird class Bird implements Flyable { private String name; public Bird(String name) { this.name = name; } @Override public void fly() { System.out.println(name + " is flying in the sky with a max speed of " + Flyable.MAX_SPEED + " km/h."); } @Override public void land() { System.out.println(name + " is landing gracefully."); } } // 实现类 Airplane class Airplane implements Flyable { private String model; public Airplane(String model) { this.model = model; } @Override public void fly() { System.out.println(model + " is flying at high altitude with a max speed of " + Flyable.MAX_SPEED + " km/h."); } } // 测试类 Main public class Main { public static void main(String[] args) { // 调用静态方法 Flyable.info(); // 输出:This is the Flyable interface. // 访问静态变量 System.out.println("Max speed for all Flyable objects: " + Flyable.MAX_SPEED + " km/h."); System.out.println(); // 创建 Bird 对象 Flyable bird = new Bird("Sparrow"); bird.fly(); // 输出:Sparrow is flying in the sky with a max speed of 1000 km/h. bird.land(); // 输出:Sparrow is landing gracefully. System.out.println(bird.MAX_SPEED + " km/h."); //1000 km/h -> 这种写法不会报错,但它实际上是 语法糖 ,编译器会自动将其转换为通过接口名访问的形式: System.out.println(Flyable.MAX_SPEED + " km/h."); System.out.println(); // 创建 Airplane 对象 Flyable airplane = new Airplane("Boeing 747"); airplane.fly(); // 输出:Boeing 747 is flying at high altitude with a max speed of 1000 km/h. airplane.land(); // 输出:Landing...(使用默认实现) } }
三、抽象类和接口的区别
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 定义方式 | 使用interface关键字定义 | 使用abstract关键字定义 |
| 成员变量 | 只能是public static final | 可以是普通变量或静态变量 |
| 构造器 | 不允许定义构造器 | 可以定义构造器 |
| 多重继承 | 支持多重实现 | 不支持多重继承 |
| 设计目的 | 定义行为规范(can-do) | 定义通用结构(is-a) |
