java学习
本文最后更新于 2025年4月17日 下午
部分来自吉林大学出版社《零基础学Java》
java学习
String
char[] a和String[] a的区别
char存储单个字符,string存储字符串对象
char[] a:数组元素以单个字符的形式存在。例如,{'H', 'e', 'l', 'l', 'o'}。String[] a:数组元素以字符串的形式存在。例如,{"Hello", "World"}。
String 实例化
可以使用String a = new String('gsbhs');创建String对象
String b = new String(a); 使用已有字符串变量实例化b
1 | |
String 连接
只要+操作符的一个操作数是字符串,编译器会自动将另一个操作数转换成String
提取 String 信息
1 | |
字符串操作
-
截取字符串
1
2str.substring(beginIndex); //返回一个新的字符串,该字符串从指定的索引beginIndex处的字符开始,直到endIndex处的字符。(beginIndex包括,endIndex不包括)
str.substring(beginIndex,endIndex); -
字符串替换
1
str.replace(oldstr,newstr); //返回一个新的字符串。oldstr为要替换的子字符串,newstr为替换后的子字符串。如果oldstr出现多次,则全部替换;如果没有找到oldstr,则返回原字符串。(oldstr大小写敏感) -
字符串分割
1
str.split(regex); //以regex为分隔符,返回一个String数组。 -
大小写转换
1
2str.toLowerCase(); //字符串中所有字符转换成小写,返回一个新的 String 对象
str.toUpperCase(); //字符串中所有字符转换成大写,返回一个新的 String 对象 -
去除空白内容
1
str.trim(); //删除字符串首尾处的空白字符,返回一个新的 String 对象 -
比较字符串是否相等
1
str.equals(str1); //当且仅当进行比较的字符串不为null且str和str1内容相同时,结果为true。null和""是2种概念。
StringBuffer类
StringBuffer类是线程安全的可变字符序列,即线程安全的可变字符串。和String本质一样,但执行效率快很多,且创建的字符串序列是可修改的,实体容量会随着存放的字符串增加而自动增加。
-
创建StringBuffer类
1
2
3
4
5
6
7
8
9
10
11
12//创建StringBuffer类必须使用new而不能像String对象那样直接引用字符串常量
//String类
// 直接引用字符串常量
String str1 = "Hello";
// 使用 new 关键字创建对象
String str2 = new String("Hello");
//StringBuffer类
// 使用 new 关键字创建 StringBuffer 对象
StringBuffer sbf = new StringBuffer(); //创建一个对象,无初始值
StringBuffer sbf = new StringBuffer("Hello"); //创建一个对象,初始值为"Hello"
StringBuffer sb = new StringBuffer(32); //创建一个对象,初始容量为32个字符 -
append()方法
1
sbf.append(obj); //obj可为任意数据类型的对象,都会转成字符串的表现形式追加到sbf。 -
setCharAt(int index, char ch)方法
1
sbf.setCharAt(idnex,ch); //将指定索引index处的字符修改为ch -
insert(int offset,String str)方法
1
2sbf.insert(offset,str); //将字符串str插入到指定的索引值offset位置上。从指定索引[offset]开始向后移,str插进去
//StringBuilder sbf1=sbf.insert(5, ", Java");先对sbf进行操作,再赋值给sbf1 -
delete(int start,int end)
1
2sbf.delete(start,end) //移除sbf内从索引start开始end结束(不包含)的子字符串。如果end-1超出最大索引范围,则一直到序列尾部。如果start=end,则不发生改变。
//该方法会直接修改调用它的 StringBuffer 或 StringBuilder 对象,而不是创建一个新的对象。 -
其他方法
有类似String类的用法,如lenth等。。。
java面向对象
类与对象(面向对象编程基础)
1 | |
成员变量的定义与普通变量的定义一样
成员方法
语法格式
1 | |
权限修饰符:private、public、protected,也可以不写,用于控制方法的访问权限。
返回值类型:用于指定方法返回值的类型,可以是任意类型。如果方法不需要返回值,则使用void关键字。方法如果有返回值,则必须使用return关键字返回一个指定返回值类型的数据。
参数:可有可无。参数可以是对象,也可是变量。
示例:
1 | |
成员方法的参数
调用方法时传给方法的值叫实参;在方法内部接收实参的变量叫形参。形参只在方法内部有效。
-
值参数
当你将一个参数以值传递的方式传递给函数或方法时,实际上传递的是该参数的一个副本,而不是参数本身。函数或方法内部对这个副本的修改不会影响到原始参数的值。对于基本数据类型,传递的是值的副本;对于引用类型,传递的是引用(内存地址)的副本。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class Book {
public static void main(String[] args) {
Book book = new Book();
int shelf = 30; //实参
int box = 40; //实参
System.out.println("把书架上的书全部放进箱子后,箱子里一共有"
+ book.add(shelf,box) + "本书。\n明细如下:书架上"
+ shelf + "本书,箱子里原有" + box + "本书。");
}
private int add(int shelf,int box) { //传形参
box = box + shelf; //形参
return box; //输出形参
}
} -
引用参数
给方法传递参数时,参数的类型是数组或其他引用类型,会将修改传递到实参。
-
不定长参数
声明方法时,有若干个相同类型的参数,可以定义为不定长参数。
1
权限修饰符 返回值类型 方法名(参数类型... 参数名)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class add {
// 定义一个可变参数(不定长参数)的加法方法
public static int add(int... x) {
int result = 0;
for (int i = 0; i < x.length; i++) {
result += x[i];
}
return result;
}
public static void main(String[] args) {
// 调用 add 方法并传入参数
int sum = add(1, 2, 3, 4, 5);
// 打印计算结果
System.out.println("这些数的和是: " + sum);
}
}
构造方法(类似python的__init__,在创建类的对象时对对象进行初始化,new的时候调用)
特点
-
方法名与类名相同
构造方法的名称必须和所在类的名称完全一致,包含大小写。
1
2
3
4
5
6public class Person {
// 构造方法,方法名与类名相同
public Person() {
System.out.println("Person 对象被创建");
}
} -
没有返回类型
构造方法没有返回类型,连
void也不用写。这是构造方法和普通方法的一个重要区别。普通方法需要明确指定返回类型,如int、String等。1
2
3
4
5
6
7
8public class Student {
// 构造方法,没有返回类型
public Student() {
System.out.println("Student 对象被创建");
}
}
Student student = new Student("John", 25); //开头的Student表示这个实例化的student对象是属于Student类的,类似定义一个String s = "123"
//java10开始可以通过var自动判断是属于哪个类,即可用var代替Student -
创建对象时自动调用
当使用
new关键字创建类的对象时,会自动调用相应的构造方法。构造方法在对象实例化的过程中起到初始化对象的作用。1
2
3
4
5
6
7
8
9
10public class Book {
public Book() { //方法名和类名同名,为构造方法
System.out.println("Book 对象被创建并初始化");
}
public static void main(String[] args) {
// 创建 Book 对象,自动调用构造方法
Book book = new Book();
}
} -
可以重载
和普通方法一样,构造方法也支持重载。也就是说,一个类中可以定义多个构造方法,只要它们的参数列表不同(参数的个数、类型或顺序不同)。通过构造方法重载,可以根据不同的需求来创建对象。
即java可以创建多个同名但参数列表不同的构造方法。通过不同的参数列表(参数的个数、类型或顺序不同)来确定使用哪个构造方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class Rectangle {
private int width;
private int height;
// 无参构造方法
public Rectangle() {
width = 0;
height = 0;
}
// 带一个参数的构造方法
public Rectangle(int side) {
width = side;
height = side;
}
// 带两个参数的构造方法
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
} -
若未定义构造方法,编译器会提供默认构造方法
-
可以使用
this或super关键字(构造方法接收外部参数,传递给类内部的成员变量,如构造方法Person接收name和age,通过this关键字传递给name和age)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Person {
String name; //定义成员变量
int age;
// 构造方法
public Person(String name, int age) {
this.name = name; //传递参数
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("John", 25);
}
}
定义语法
1 | |
局部变量
局部变量在方法执行时被创建,执行结束时被销毁。使用前必须先赋值或初始化。
作用域
1 | |
重复声明的问题
1 | |
this关键字
this可调用成员方法、成员变量和构造方法。
当成员变量和局部变量同名时,会优先使用局部变量,成员变量可通过this关键字使用。
1 | |
this也可以被返回
1 | |
this也可以调用类中的构造方法(this()语句前不可以有其他代码)
1 | |
在静态方法里不能使用 this 关键字。因为 this 依赖于对象实例,而静态方法可以在没有创建对象实例的情况下直接调用。可以使用类名.静态/局部变量。
静态方法
静态方法里不能使用this:
Java 程序运行时,当一个类被加载进 JVM(Java 虚拟机)时,静态方法就已经被分配好了内存空间,可直接通过类名调用,它的存在不依赖于类的实例化。也就是说,即使没有创建该类的任何实例,静态方法也能正常使用。而 this 关键字代表当前对象的引用,其存在的前提是有类的实例,没有创建实例就不能使用,因此静态方法里不能有this。
静态方法里不能直接使用非静态变量和非静态方法:
静态方法属于类本身,不依赖于类的实例,在类加载时就已经存在。而静态变量同样属于类,在类加载时初始化,被该类的所有实例共享。因此,静态方法可以直接调用静态变量,但不能直接调用非静态变量,因为非静态变量是与类的实例相关联的,每个实例可能有不同的值。而静态方法在类加载时就存在,此时可能还没有创建类的实例,无法确定要访问哪个实例的非静态变量,因此不能直接调用非静态变量。静态方法里不能使用非静态方法同理。
总结:静态方法里可以使用静态变量和局部变量,不能使用this关键字,可实例化一个对象再调用这个对象内的方法或变量。
使用场景
如果想使用类中的成员方法,需要先将这个类进行实例化。使用静态方法无需创建对象实例,方便调用。
调用语法
1 | |
示例
1 | |
静态代码块
1 | |
- **静态代码块属于类,在类被加载时执行,所以只执行一次。**静态代码块的目的是为类的静态成员变量进行初始化操作,或者执行一些只需要在类加载时执行一次的操作,比如加载配置文件、初始化数据库连接池等。由于类在整个 JVM 生命周期内只会被加载一次,所以静态代码块也只会执行一次。
- 非静态代码块属于类的实例,所以每次创建对象时,非静态代码块都会执行一次。非静态代码块会在构造方法之前运行。
- 构造方法在创建对象时运行。
- **在内存中,静态变量只有一份拷贝,被类的所有实例共享,无论通过类名还是类的某个实例来访问和修改静态变量,都是对内存中同一份静态变量进行操作。所以,当在某个实例里修改静态变量的值时,这个修改会立即反映到类以及该类的其他所有实例中。**所以第二个实例
test3返回test2非静态代码块。 - 成员方法只有在使用对象调用时才会运行。
类的主方法
1 | |
- **主方法是静态的。**所以在主方法调用其他方法时,其他方法也必须时静态的。
- 主方法没有返回值。
- **主方法的形参为数组。**可以使用args.length获取参数的个数。
面向对象核心技术
类的封装
…
类的继承
基本思想
基于某个父类的扩展,制定一个新的子类。子类可以继承父类原有的属性和方法,也可增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。
extends 关键字
让一个类继承另一个类需要使用extends关键字。
1 | |
一个类只可以有一个父类。
1 | |
1 | |
重写父类方法时,方法的权限只能从小范围到大范围改变。
super 关键字
super 关键字代表父类对象,可以在子类重构父类的方法或属性后调用父类的方法或属性。
1 | |
所有类的父类——Object类
-
getClass()方法1
2getClass().getName();
//getClass()方法会返回某个对象执行时的Class实例,然后通过Class实例调用getName()方法获取类的名称 -
toString()方法1
2
3
4
5
6
7
8
9
10public class Hello {
public String toString() {
return "Say" + getClass().getName() + "to Java";
}
public static void main(String[] args) {
System.out.println(new Hello());
}
}
//toString()方法会返回某个对象的字符串表示形式,当打印某个类对象时,将自动调用重写的toString()方法 -
equals()方法
比较2个对象的引用地址是否相等。
1 | |