java
例:
public class zh{
public void main(String[] args){
System.out.println("hello,world.");
}
}
类:
一个文件可以有多个类,但只能有一个主类(即Public类)。类里有属性,有方法。
定义类:class关键字
class xxx {
//属性
int a;
string b;
//方法
void print(){
System.out.println("hello");
}
}
*修饰符:
用来定义类,方法,变量:1.访问修饰符;2.非访问修饰符。
访问修饰符:
| public(公共): | 可在不同包中访问 |
|---|---|
| protected(被保护): | 仅在同一包内或子类可访问 |
| private(私有): | 仅在同一类里可访问 |
| 默认访问修饰符: | 仅同一包内可访问 |
非访问修饰符:
static;final,abstract,synchronized,transient,volatile
基础:
基本数据类型:
六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte,short,int,long,float,double,char,boolean.
变量类型:
局部变量:在方法,函数或块内部声明;
实例变量(成员变量):在类中声明;
类变量(静态变量):在类中用static关键字声明(仅初始化一次);
参数变量:在参数位置声明
运算符:
算数,自增自减,赋值,关系(比较),逻辑,位,条件
instanceof:判断某实例是否为某个类或接口
例:
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
循环结构:
1.while 2.do…while 3.for
特殊:增强for循环
for(声明语句 : 表达式){
//块
}
//例
String[] names = {"zhangsan","lisi","wangwu"};
for(String name : names){
System.out.println(name);
}
break,continue关键字;
条件语句:
if…else,switch case。
*数据类型转换:
隐式转换:byte -> short -> int -> long -> float -> double
显式转换(强制转换):
1.基本数据类型转字符串:String.valueOf() 或者 +
int x = 10;
String y = String.valueOf(x);
String z = x + '';
2.字符串转基本数据类型:xx.parsexx()
String s = "123";
int x = Integer.parseInt(s);
double y = Double.parseDouble(s);
3.基本类型之间的转换:.xxValue()
Number num = 1234.56; //实际是Double类型
System.out.println(num.intValue()); // 1234 (截断小数)
System.out.println(num.longValue()); // 1234
System.out.println(num.floatValue()); // 1234.56
System.out.println(num.doubleValue()); // 1234.56
Number类&Math类:
Number类:
| 类名 | 对应基本类型 | 描述 |
|---|---|---|
| Byte | byte | 字节型包装类 |
| Short | short | 短整型包装类 |
| Integer | int | 整型包装类 |
| Long | long | 长整型包装类 |
| Float | float | 单精度浮点型包装类 |
| Double | double | 双精度浮点型包装类 |
| BigInteger | – | 不可变任意精度整数 |
| BigDecimal | – | 不可变任意精度有符号十进制数 |
Integer x = 3就是java编译器进行了自动装箱,即:Integer x = Integer.valueOf(3)
例:int和Integer的区别
| 对比维度 | int x = 3 | Integer x = 3 |
|---|---|---|
| 类型 | 基本数据类型 | 引用类型(包装类) |
| 本质 | 就是一个数字 3,存在栈里 | 是一个对象,存的是堆里对象的地址 |
| 默认值 | 0 | null(这是最关键的坑之一) |
| 能否为 null | 不能 | 能(表示“没有值”) |
| 内存占用 | 4 字节,轻量 | 约 16 字节(对象头 + 内部 int 值),有开销 |
| 方法支持 | 没有方法 | 有,比如 toString()、compareTo()、parseInt() |
| 集合支持 | 不支持(List<int> 编译报错) | 支持(List<Integer> 是合法的) |
比较:
// 情况一:int 与 int 比较 —— 直接比数值
int a = 128;
int b = 128;
System.out.println(a == b); // true
// 情况二:Integer 与 Integer 比较 —— 比的是地址!
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false (超出缓存范围,是两个不同对象)
// 情况三:但如果是 127 呢?
Integer e = 127;
Integer f = 127;
System.out.println(e == f); // true (因为 Integer 有缓存池)
//因此一般用equals()进行比较
Integer x = 200;
Integer y = 200;
System.out.println(x.equals(y)); // true 这才是正确的比较方式
Math类:
1.指对运算:
Math.exp(1); // e^1 ≈ 2.718
Math.log(Math.E); // ln(e) = 1
Math.log10(100); // log10(100) = 2
2.随机数:
// 生成[0.0, 1.0)之间的随机数
double random = Math.random();
// 生成[1, 100]的随机整数
int randomInt = (int)(Math.random() * 100) + 1;
3.toString():将对象以字符串的形式返回
// 数字、字符串、日期、集合,直接打印就很清晰
Integer num = 123;
System.out.println(num.toString()); // 输出: "123"
String text = "Hello";
System.out.println(text.toString()); // 输出: "Hello"
Date now = new Date();
System.out.println(now.toString()); // 输出: Sat May 02 12:42:33 CST 2026
ArrayList<String> list = new ArrayList<>();
list.add("苹果");
list.add("香蕉");
System.out.println(list.toString()); // 输出: [苹果, 香蕉]
4.Math.abs():返回绝对值
5.Math.ceil():向上取整
6.Math.floor():向下取整
7.Math.round():四舍五入
8.Math.pow():二次方
9.Math.sqrt():算数平方根
Character类:
转义序列:
| 转义序列 | 描述 |
|---|---|
| \t | 在文中该处插入一个tab键 |
| \b | 在文中该处插入一个后退键 |
| \n | 在文中该处换行 |
| \r | 在文中该处插入回车 |
| \f | 在文中该处插入换页符 |
| ‘ | 在文中该处插入单引号 |
| “ | 在文中该处插入双引号 |
| \ | 在文中该处插入反斜杠 |
| 序号 | 方法与描述 |
|---|---|
| 1 | isLetter() 是否是一个字母 |
| 2 | isDigit()是否是一个数字字符 |
| 3 | isWhitespace() 是否是一个空白字符 |
| 4 | isUpperCase() 是否是大写字母 |
| 5 | isLowerCase() 是否是小写字母 |
| 6 | toString() 返回字符的字符串形式,字符串的长度仅为1 |
*String类:
创建字符串:
//直接创建,存储在堆中
String x = "123";
//使用New创建
String x = new String("123");
//由字符数组转为字符串
char[] array = {"1","2","3"};
String x= new String(array);//x= "123"
长度:
int len = x.lenght();
连接字符串:
//concat方法
string1.concat(string2);
//+
string1 + string2;
创建格式化字符串:
//format方法
String fs;
fs = String.format("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);
常见方法:
1.按字典顺序比较:int compareTo(String str);
2.字符串是否以指定的后缀结束:boolean endsWith(String str)
3.将字符串与指定对象比较:boolean equals(Object O)
4.返回第一次出现指定字符串的索引:int indexof(String str)
5.判断是否匹配给定的正则表达式:boolean matchs(String regex)
6.根据正则表达式拆分字符串:String[] split(String regex)
7.将字符串转为字符数组:char[] toCharArray()
8.判断字符串是否为空:isEmpty()
修改字符串:
注:String 本身不能修改,需要使用StringBuffer类或StringBuilder类
public class Test{
public static void main(String[] args){
StringBuilder sb = new StringBuilder(10);//创建大小为10,类似字符数组的空间
sb.append("123..");//通过append像空间中添加
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");//用insert在第8个开始插入
System.out.println(sb);
sb.delete(5,8);//删除[5,8)
System.out.println(sb);
}
}
*数组:
声明:
dataType[] arrayRefVar; // 首选的方法
或
dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建:
//使用new创建
array = new int[10];
//声明的同时进行创建
int[] array = new int[10];
//直接初始化
int[] array ={1,2,3,4,5};
多维数组:
String[][] str = new String[3][4];
每列单独创建空间:
String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
输入输出
输出:System.out.println()
*输入:Scanner类
导包:
import java.util.Scanner;
创建对象:
Scanner scan = new Scanner(System.in);
通过next()或nextLine()读取字符串:
String name = scan.next();//以空白为分隔符或结束符
String name = scan.nextLine();//以Enter为结束符
读取数字:
int x = scan.nextInt();
double y = scan.nextDouble();
//读取前先判断
if(scan.hasNextInt()){
int i =scan.nextInt();
}
关闭:scan.close();
*面向对象
类(Class):
- 定义对象的蓝图,包括属性和方法。
- 示例:
public class Car { ... }
方法(Method):
- 定义类的行为,包含在类中的函数。
- 示例:
public void displayInfo() { System.out.println("Info"); }
类方法:
static修饰的方法。
| 特性 | 类方法(static) | 实例方法 |
|---|---|---|
| 属于 | 类本身 | 对象 |
| 调用方式 | 类名.方法名() | 对象.方法名() |
是否有 this | ❌ | ✅ |
| 访问实例变量 | ❌(需通过对象) | ✅ |
| 访问类变量 | ✅ | ✅ |
| 是否可重写 | ❌(可隐藏) | ✅ |
对象(Object):
- 类的实例,具有状态和行为。
- 示例:
Car myCar = new Car();
创建对象:
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。
public class Puppy{
public Puppy(String name){
//这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public static void main(String[] args){
// 下面的语句将创建一个Puppy对象
Puppy myPuppy = new Puppy( "tommy" );
}
}
构造方法:
- 初始化对象属性
- 与类同名的方法,创建类时自动调用该方法。
- 一个类至少有一个构造方法,可有多个构造方法,但参数不同。
继承(Inheritance):
- 一个类可以继承另一个类的属性和方法。
- 示例:
public class Dog extends Animal { ... }
格式:
class 父类 {
}
class 子类 extends 父类 {
}
关键字:
extends:声明继承哪个父类。
super:引用父类对象,访问父类成员。
this:指向自己的引用。
final:声明该类无法被继承。
例:
//父类
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
//子类
class Dog extends Animal {
void eat() {//重写方法
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
继承特性:
- 子类继承父类后可直接使用父类中声明的非private属性和方法,也可以重新声明。
- 一个子类只能继承一个父类
- 不继承父类的构造器,写子类构造器时,如果父类构造器带参数,需要用
super()传入参数,若无参数自动调用。
封装(Encapsulation):
- 将对象的状态(字段)私有化(private),通过公共方法(public)访问。
- 示例:private String name;
public String getName() { return name; }
多态(Polymorphism):
- 对象可以表现为多种形态,主要通过方法重载和方法重写实现。
- 示例:
- 方法重载:
public int add(int a, int b) { ... }和public double add(double a, double b) { ... } - 方法重写:
@Override public void makeSound() { System.out.println("Meow"); }
- 方法重载:
方法重载(Method Overload):
- 同一个类中可以有多个同名的方法,但参数不同。
- 示例:
public class MathUtils {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
方法重写(Method Override):
- 子类重写父类中的方法
- 重写的方法参数列表需相同
- 访问权限不能比父类方法低
final,static和private方法不能被重写- 通过
@Override强制检查重写是否正确。
抽象(Abstraction):
- 使用抽象类和接口来定义必须实现的方法,不提供具体实现。
- 抽象类不能被实例化,只能被继承,只有抽象类的非抽象子类可以创建对象。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含方法体。
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
- 示例:
- 抽象类:
public abstract class Shape { abstract void draw(); } - 接口:
public interface Animal { void eat(); }
- 抽象类:
接口(Interface):
定义类必须实现的方法,支持多重继承。
注:接口类似抽象类,但与抽象类不同
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
接口的声明:
interface关键字:
interface Animal {
public void eat();
public void behavior();
}
接口的实现:
implements关键字:
public class MammalInt implements Animal{
//实现接口的方法
public void eat(){
System.out.println("Mammal eats");
}
public void behavior(){
System.out.println("Mammal behavior");
}
//声明自己的方法
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
重写接口中声明的方法时,注意:
- 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
- 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
- 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
接口的继承:
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
类的多继承是不合法,但接口允许多继承。
一个类可以继承一个普通父类或抽象类,可以继承多个接口;一个接口可以继承多个接口
*异常处理
分类:
检查性异常:
编译时强制程序员处理。通常用try-catch块捕获并处理异常,或用throws声明可能抛出的异常。
运行时异常:
编译时不要求必须处理。
错误:
JVM或系统底层发生的严重故障,程序无法通过代码修复这类问题
常见例子:
OutOfMemoryError(内存溢出)StackOverflowError(栈溢出,比如递归太深)NoClassDefFoundError(类找不到)
关键字:
| 关键字 | 作用 | 使用位置 |
|---|---|---|
try | 包裹可能抛出异常的代码 | 方法体内 |
catch | 捕获并处理特定类型的异常 | 紧跟try块 |
finally | 无论是否异常都执行的代码块(资源清理) | 紧跟catch或try |
throw | 手动抛出一个异常对象 | 方法体内 |
throws | 声明方法可能抛出的异常,交给调用者处理 | 方法签名 |
try-catch-finally:
try {
// 可能抛出异常的代码
} catch (异常类型1 e) {
// 处理异常类型1
} catch (异常类型2 e) {
// 处理异常类型2
} finally {
// 无论是否异常,都会执行的代码(通常用于释放资源)
}
throw/throws:
throw:手动抛出异常
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("取款金额必须大于0");
}
}
throws:声明异常(表明该方法会出现xx异常),交给调用者处理
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
// 不在这里处理异常,让调用者处理
}
自定义异常:
- 定义一个异常类且继承Exception类或RuntimeException类
- 写两个构造器,一个无参,一个有参。
public class YourExceptionName extends Exception /* 或 RuntimeException */ {
// 1. 无参构造
public YourExceptionName() {
super();
}
// 2. 带消息构造(必写,最常用)
public YourExceptionName(String message) {
super(message);
}
}
*多线程
并发:多个指令在CPU上交替执行
并行:多个指令在CPU上同时执行
线程的生命周期:
- 新建状态:使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
- 就绪状态:当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
- 运行状态:如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
- 阻塞状态:如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
- 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
- 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
- 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
- 死亡状态:一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
| 状态 | 说明 | 进入条件 |
|---|---|---|
| NEW | 新建,还没 start | new Thread() 之后 |
| RUNNABLE | 可运行(就绪或正在运行) | 调了 start() |
| BLOCKED | 阻塞,等锁 | 竞争 synchronized 锁失败 |
| WAITING | 无限期等待 | 调了 wait() / join() / park() |
| TIMED_WAITING | 限时等待 | 调了 sleep(ms) / wait(timeout) / join(ms) |
| TERMINATED | 终止 | run() 执行完或异常退出 |
创建线程的三种方式:
给线程设置名字:setName();获取名字:getName();获取当前线程的对象:Thread.currentThread()
*1.继承Thread类
class MyThread extends Thread {//1.创建一个类(线程)继承Thread类
@Override
public void run() {//2.重写run方法(该线程需要执行的指令)
System.out.println("线程执行中:" + Thread.currentThread().getName());//继承了Thread类,可直接用getName()
}
}
// 使用
MyThread t = new MyThread();//3.创建对象
t.start();//4.执行run方法
*2.实现Runnable接口
class MyRunnable implements Runnable {//1.创建类(线程),实现Runnable接口
@Override
public void run() {//2.重写run方法
System.out.println("线程执行中:" + Thread.currentThread().getName());
}
}
// 使用
MyRunnable mr = new MyRunnable();//创建自己类的对象
Thread t = new Thread(mr);//创建线程,并传入对象
t.start();//启动线程
3.实现callable接口(略)
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
class MyCallable implements Callable<Integer> {//<Integer>泛型
@Override
public Integer call() throws Exception {
return 42;
}
}
// 使用
FutureTask<Integer> task = new FutureTask<>(new MyCallable());
Thread t = new Thread(task);
t.start();
Integer result = task.get(); // 获取返回值
