1 Java中的变量
Java 变量就好像一个容器,可以保存程序在运行过程中的值,它在声明的时候会定义对应的数据类型(Java 分为两种数据类型:基本数据类型和引用数据类型)。变量按照作用域的范围又可分为三种类型:局部变量,成员变量和静态变量。
1.1 局部变量
1.1.1 局部变量的特点
-
作用域:
- 局部变量的作用域仅限于声明它的方法、构造方法或语句块内部。一旦超出这个范围,变量将不再可用。
-
生命周期:
- 局部变量的生命周期从声明它的语句开始,到包含它的方法、构造方法或语句块执行结束时结束。
-
访问修饰符:
- 局部变量不能使用访问修饰符(如
public
,private
,protected
),因为它们的作用域仅限于方法内部。
- 局部变量不能使用访问修饰符(如
-
存储位置:
- 局部变量通常存储在栈(Stack)上。栈是一种后进先出(LIFO)的数据结构,用于存储方法调用和局部变量。
-
初始化:
- 局部变量必须在使用前进行初始化,否则编译器会报错。这是因为局部变量没有默认值,不像类的成员变量(实例变量)那样有默认值。
1.1.2 示例代码分析
在示例中:
public class LocalVariable {public static void main(String[] args) {int a = 10;int b = 10;int c = a + b;System.out.println(c);}
}
a
,b
,c
都是局部变量,它们在main
方法中声明和使用。- 这些变量的作用域仅限于
main
方法内部。 - 当
main
方法执行完毕后,这些变量将被销毁,不再占用内存。
1.1.2 其他注意事项
-
嵌套块中的局部变量:
- 如果在方法内部有嵌套的代码块(如
if
语句、for
循环等),每个代码块都可以有自己的局部变量。这些变量的作用域仅限于它们所在的代码块。
- 如果在方法内部有嵌套的代码块(如
-
变量名冲突:
- 如果在嵌套的代码块中声明了与外部代码块同名的局部变量,内部代码块中的变量将“遮蔽”外部代码块中的同名变量。
示例:嵌套块中的局部变量
public class LocalVariableExample {public static void main(String[] args) {int a = 10;if (a > 5) {int b = 20; // 局部变量 b 仅在 if 语句块中有效System.out.println(a + b); // 输出 30}// System.out.println(b); // 编译错误,b 在此处不可见}
}
在这个示例中,变量 b
仅在 if
语句块中有效,超出这个范围后,b
将不再可用。
1.2 成员变量
1.2.1 成员变量的特点
-
声明位置:
- 成员变量声明在类中,但在方法、构造方法和语句块之外。它们属于类的实例(对象),而不是方法或代码块。
-
生命周期:
- 成员变量的生命周期与对象的生命周期一致。当对象被创建时,成员变量也随之创建;当对象被销毁时,成员变量也随之销毁。
-
访问方式:
- 成员变量只能通过类的实例(对象)来访问。例如,在示例中,通过
iv.data
访问成员变量data
。
- 成员变量只能通过类的实例(对象)来访问。例如,在示例中,通过
-
访问修饰符:
- 成员变量可以使用访问修饰符(如
public
,private
,protected
)来控制其可见性。通常情况下,成员变量应该设为私有(private
),并通过公共的 getter 和 setter 方法来访问和修改。
- 成员变量可以使用访问修饰符(如
-
默认值:
- 成员变量具有默认值。数值型变量的默认值是
0
,布尔型变量的默认值是false
,引用类型变量的默认值是null
。
- 成员变量具有默认值。数值型变量的默认值是
1.2.2 示例代码分析
在示例中:
public class InstanceVariable {int data = 88;public static void main(String[] args) {InstanceVariable iv = new InstanceVariable();System.out.println(iv.data); // 88}
}
data
是一个成员变量,它声明在类InstanceVariable
中,但在方法体外。iv
是一个引用类型的变量,它引用了一个InstanceVariable
类的实例(对象)。- 通过
new InstanceVariable()
创建了一个对象,并将其引用赋值给iv
。 - 通过
iv.data
可以访问成员变量data
,并输出其值88
。
1.2.3 其他注意事项
-
初始化:
- 成员变量可以在声明时直接初始化,也可以在构造方法中进行初始化。如果未显式初始化,它们将使用默认值。
-
静态变量:
- 除了成员变量,Java 中还有静态变量(类变量)。静态变量使用
static
关键字声明,它们属于类本身,而不是类的实例。静态变量在类加载时创建,并且在整个程序运行期间都存在。
- 除了成员变量,Java 中还有静态变量(类变量)。静态变量使用
1.3 静态变量
1.3.1 静态变量的特点
-
声明位置:
- 静态变量在类中以
static
关键字声明,但必须在方法、构造方法和语句块之外。它们属于类本身,而不是类的实例。
- 静态变量在类中以
-
共享性:
- 无论一个类创建了多少个对象,类只拥有静态变量的一份拷贝。所有对象共享这个静态变量。
-
访问方式:
- 静态变量可以通过类名直接访问,不需要创建类的实例。例如,在示例中,通过
StaticVariable.data
访问静态变量data
。
- 静态变量可以通过类名直接访问,不需要创建类的实例。例如,在示例中,通过
-
存储位置:
- 静态变量存储在静态存储区(也称为方法区)。静态存储区在程序开始时创建,在程序结束时销毁。
-
生命周期:
- 静态变量的生命周期从程序开始时创建,到程序结束时销毁。
-
可见性:
- 静态变量具有与成员变量相似的可见性。为了对类的使用者可见,大多数静态变量声明为
public
类型。
- 静态变量具有与成员变量相似的可见性。为了对类的使用者可见,大多数静态变量声明为
-
默认值:
- 静态变量的默认值与实例变量相似。数值型变量的默认值是
0
,布尔型变量的默认值是false
,引用类型变量的默认值是null
。
- 静态变量的默认值与实例变量相似。数值型变量的默认值是
1.3.2 示例代码分析
在你的示例中:
public class StaticVariable {static int data = 99;public static void main(String[] args) {System.out.println(StaticVariable.data); // 99}
}
data
是一个静态变量,它声明在类StaticVariable
中,并在声明时初始化为99
。- 通过
StaticVariable.data
可以直接访问静态变量data
,不需要创建类的实例。
1.3.3 其他注意事项
-
静态初始化块:
- 静态变量可以在静态语句块中初始化。静态语句块在类加载时执行,并且只执行一次。
-
常量:
- 静态变量通常用于声明常量。常量使用
final
关键字修饰,并且通常声明为public static final
。
- 静态变量通常用于声明常量。常量使用
1.3.4 示例:静态变量的初始化和静态初始化块
public class StaticVariableExample {public static int data; // 静态变量// 静态初始化块static {data = 99;System.out.println("静态初始化块执行");}public static void main(String[] args) {System.out.println(StaticVariableExample.data); // 99}
}
在这个示例中:
data
是一个静态变量,它在静态初始化块中被初始化为99
。- 静态初始化块在类加载时执行,并且只执行一次。
- 在
main
方法中,通过StaticVariableExample.data
访问静态变量data
。
1.4 常量
1.4.1 常量的特点
-
不可变性:
- 常量使用
final
关键字修饰,一旦赋值后,其值无法改变。常量的值在声明时必须初始化,否则编译器会报错。
- 常量使用
-
命名规范:
- 常量的命名通常采用全大写字母,单词之间用下划线分隔(例如:
UP_DIRECTION
)。这种命名规范有助于区分常量和普通变量。
- 常量的命名通常采用全大写字母,单词之间用下划线分隔(例如:
-
作用:
- 代表常数:常量可以用来表示不会改变的数值或字符串,便于修改和维护。例如,圆周率的值可以定义为常量
final double PI = 3.14
。 - 增强可读性:常量可以用来表示具有特定含义的值,增强程序的可读性。例如,方向可以用常量
final int UP = 0
和final int DOWN = 1
表示。
- 代表常数:常量可以用来表示不会改变的数值或字符串,便于修改和维护。例如,圆周率的值可以定义为常量
1.4.2 示例代码分析
在示例中:
public class FinalVariable {final String CHEN = "沉";static final String MO = "默";public static void main(String[] args) {FinalVariable fv = new FinalVariable();System.out.println(fv.CHEN); // 输出 "沉"System.out.println(MO); // 输出 "默"}
}
CHEN
是一个实例常量,使用final
关键字修饰,值为"沉"
。MO
是一个静态常量,使用static final
关键字修饰,值为"默"
。- 在
main
方法中,通过fv.CHEN
访问实例常量CHEN
,通过MO
访问静态常量MO
。
1.4.3 其他注意事项
-
初始化时机:
- 实例常量必须在声明时或在构造方法中初始化。
- 静态常量必须在声明时或在静态初始化块中初始化。
-
常量的使用场景:
- 常量通常用于表示不会改变的配置参数、数学常数、枚举值等。
2 Java中的方法
2.1 Java中的方法是什么
方法用来实现代码的可重用性,我们编写一次方法,并多次使用它。通过增加或者删除方法中的一部分代码,就可以提高整体代码的可读性。
只有方法被调用时,它才会执行。Java 中最有名的方法当属 main() 方法,这是程序的入口。
2.2 如何声明方法
2.2.1 方法的声明
方法的声明包括以下几个部分:
-
访问权限:
- 指定方法的可见性。Java 提供了四种访问权限修饰符:
public
:该方法可以被所有类访问。private
:该方法只能在定义它的类中访问。protected
:该方法可以被同一个包中的类,或者不同包中的子类访问。default
(不写访问修饰符):该方法只能被同一个包中的类可见。
- 指定方法的可见性。Java 提供了四种访问权限修饰符:
-
返回类型:
- 方法返回的数据类型,可以是基本数据类型(如
int
,double
)、对象(如String
)、集合(如List
)等。如果方法不需要返回数据,则使用void
关键字。
- 方法返回的数据类型,可以是基本数据类型(如
-
方法名:
- 方法名最好反映出方法的功能。方法名通常是一个动词,并且以小写字母开头。如果方法名包含多个单词,第一个单词通常是动词,后续单词可以是形容词或名词,并采用驼峰命名法。
- 示例:
sum()
:一个单词的方法名。stringComparison()
:多个单词的方法名。
-
参数列表:
- 参数放在圆括号内,如果有多个参数,可以使用逗号隔开。参数包括参数类型和参数名。如果方法没有参数,圆括号是空的。
- 示例:
int add(int a, int b)
:包含两个参数的方法。void printMessage()
:没有参数的方法。
-
方法签名:
- 方法签名包括方法名和参数列表。方法签名用于唯一标识一个方法。
-
方法体:
- 方法体放在一对花括号
{}
内,包含执行特定任务的代码。
- 方法体放在一对花括号
2.2.2 示例代码
下面是一个完整的示例,展示了如何声明和调用一个方法:
public class MethodExample {// 声明一个公共方法,计算两个整数的和public int add(int a, int b) {return a + b;}// 声明一个私有方法,打印消息private void printMessage() {System.out.println("Hello, World!");}// main 方法是程序的入口public static void main(String[] args) {MethodExample example = new MethodExample();// 调用 add 方法int result = example.add(5, 3);System.out.println("Sum: " + result); // 输出 "Sum: 8"// 调用 printMessage 方法example.printMessage(); // 输出 "Hello, World!"}
}
在这个示例中:
add
方法是一个公共方法,接受两个int
类型的参数,并返回它们的和。printMessage
方法是一个私有方法,没有参数,也没有返回值,用于打印一条消息。- 在
main
方法中,我们创建了MethodExample
类的实例,并调用了add
和printMessage
方法。
2.3 方法有哪几种
2.3.1 方法的分类
方法可以分为以下两种主要类型:
-
标准类库方法(预先定义方法):
- Java 提供了大量预先定义好的方法供我们调用,这些方法通常是标准类库的一部分。这些方法已经由 Java 开发团队实现,可以直接在代码中使用。
- 例如:
String
类的length()
、equals()
、compareTo()
方法。System.out.println()
方法,用于在控制台打印信息。Math
类的sqrt()
、pow()
、abs()
方法,用于数学计算。
-
用户自定义方法:
- 当标准类库方法无法满足特定需求时,开发者可以自定义方法。用户自定义方法是由开发者自己编写的,用于实现特定的功能。
- 用户自定义方法可以分为静态方法和实例方法:
- 静态方法:使用
static
关键字修饰,属于类本身,不需要创建类的实例即可调用。静态方法通常用于工具类或辅助方法。 - 实例方法:不使用
static
关键字修饰,属于类的实例,需要通过类的实例来调用。实例方法通常用于操作对象的状态或行为。
- 静态方法:使用
2.3.2 示例代码
下面是一个示例,展示了标准类库方法和用户自定义方法的使用:
public class MethodExample {// 用户自定义方法:计算两个整数的和public int add(int a, int b) {return a + b;}// 用户自定义静态方法:打印消息public static void printMessage(String message) {System.out.println(message);}public static void main(String[] args) {// 使用标准类库方法:String 类的 length() 方法String name = "沉默王二";int length = name.length();System.out.println("字符串长度: " + length); // 输出 "字符串长度: 4"// 使用标准类库方法:System.out.println() 方法System.out.println("Hello, World!"); // 输出 "Hello, World!"// 使用用户自定义方法:add 方法MethodExample example = new MethodExample();int result = example.add(5, 3);System.out.println("Sum: " + result); // 输出 "Sum: 8"// 使用用户自定义静态方法:printMessage 方法printMessage("这是一个静态方法的调用"); // 输出 "这是一个静态方法的调用"}
}
在这个示例中:
add
方法是一个用户自定义的实例方法,用于计算两个整数的和。printMessage
方法是一个用户自定义的静态方法,用于打印消息。- 在
main
方法中,我们使用了标准类库方法(如String
类的length()
方法和System.out.println()
方法),以及用户自定义方法(如add
方法和printMessage
方法)。
2.4 什么是实例方法
2.4.1 实例方法的特点
-
非静态方法:
- 实例方法没有使用
static
关键字修饰,属于类的实例。因此,在调用实例方法之前,必须创建类的对象。
- 实例方法没有使用
-
调用方式:
- 实例方法的调用方式是
对象名.方法名()
。例如,instanceMethodExample.add(1, 2)
调用InstanceMethodExample
类的实例方法add()
。
- 实例方法的调用方式是
-
访问实例变量:
- 实例方法可以直接访问类的实例变量(成员变量)。例如,
this.name
访问当前对象的name
变量。
- 实例方法可以直接访问类的实例变量(成员变量)。例如,
2.4.2 示例代码
下面是一个示例,展示了如何声明和调用实例方法:
public class InstanceMethodExample {public static void main(String[] args) {// 创建 InstanceMethodExample 对象InstanceMethodExample instanceMethodExample = new InstanceMethodExample();// 调用实例方法 addint result = instanceMethodExample.add(1, 2);System.out.println("Sum: " + result); // 输出 "Sum: 3"}// 实例方法:计算两个整数的和public int add(int a, int b) {return a + b;}
}
在这个示例中:
add
方法是一个实例方法,用于计算两个整数的和。- 在
main
方法中,我们创建了InstanceMethodExample
类的实例instanceMethodExample
,并通过该实例调用了add
方法。
2.4.3 特殊类型的实例方法:getter 和 setter 方法
-
getter 方法:
- getter 方法用于获取私有变量(
private
修饰的字段)的值。getter 方法的命名通常以get
开头,后跟变量名(首字母大写)。
- getter 方法用于获取私有变量(
-
setter 方法:
- setter 方法用于设置私有变量的值。setter 方法的命名通常以
set
开头,后跟变量名(首字母大写)。
- setter 方法用于设置私有变量的值。setter 方法的命名通常以
2.4.4 示例:getter 和 setter 方法
public class Person {private String name;private int age;private int sex;// getter 方法:获取 name 的值public String getName() {return name;}// setter 方法:设置 name 的值public void setName(String name) {this.name = name;}// getter 方法:获取 age 的值public int getAge() {return age;}// setter 方法:设置 age 的值public void setAge(int age) {this.age = age;}// getter 方法:获取 sex 的值public int getSex() {return sex;}// setter 方法:设置 sex 的值public void setSex(int sex) {this.sex = sex;}public static void main(String[] args) {// 创建 Person 对象Person person = new Person();// 使用 setter 方法设置属性值person.setName("沉默王二");person.setAge(30);person.setSex(1);// 使用 getter 方法获取属性值System.out.println("Name: " + person.getName()); // 输出 "Name: 沉默王二"System.out.println("Age: " + person.getAge()); // 输出 "Age: 30"System.out.println("Sex: " + person.getSex()); // 输出 "Sex: 1"}
}
在这个示例中:
Person
类包含三个私有变量:name
、age
和sex
。- 每个私有变量都有一个对应的 getter 方法和 setter 方法。
- 在
main
方法中,我们创建了Person
类的实例person
,并使用 setter 方法设置属性值,使用 getter 方法获取属性值。
2.5 什么是静态方法
2.5.1 静态方法的特点
-
静态方法的声明:
- 静态方法使用
static
关键字修饰,属于类本身,而不是类的实例。因此,静态方法可以直接通过类名调用,不需要创建类的实例。
- 静态方法使用
-
调用方式:
- 静态方法的调用方式是
类名.静态方法名()
。例如,StaticMethodExample.add(1, 2)
调用StaticMethodExample
类的静态方法add()
。
- 静态方法的调用方式是
-
访问限制:
- 静态方法只能访问静态变量和静态方法,不能直接访问实例变量和实例方法。如果需要访问实例变量或实例方法,必须通过类的实例来调用。
-
工具类:
- 静态方法通常用于工具类或辅助方法,这些方法不需要访问类的实例变量,也不需要创建类的实例。例如,
Math
类中的许多方法(如sqrt()
、pow()
、abs()
)都是静态方法。
- 静态方法通常用于工具类或辅助方法,这些方法不需要访问类的实例变量,也不需要创建类的实例。例如,
2.5.2 示例代码
下面是一个示例,展示了如何声明和调用静态方法:
public class StaticMethodExample {public static void main(String[] args) {// 调用静态方法 addint result = add(1, 2);System.out.println("Sum: " + result); // 输出 "Sum: 3"}// 静态方法:计算两个整数的和public static int add(int a, int b) {return a + b;}
}
在这个示例中:
add
方法是一个静态方法,用于计算两个整数的和。- 在
main
方法中,我们直接调用了静态方法add
,而不需要创建StaticMethodExample
类的实例。
2.5.3 静态方法与实例方法的区别
-
调用方式:
- 静态方法通过类名调用,实例方法通过对象名调用。
-
访问变量:
- 静态方法只能访问静态变量和静态方法,实例方法可以访问实例变量和实例方法。
-
生命周期:
- 静态方法在类加载时创建,实例方法在对象创建时创建。
2.5.4 示例:静态方法与实例方法的对比
public class MethodComparison {// 静态变量static int staticVar = 10;// 实例变量int instanceVar = 20;// 静态方法:访问静态变量public static void printStaticVar() {System.out.println("静态变量: " + staticVar);}// 实例方法:访问实例变量public void printInstanceVar() {System.out.println("实例变量: " + instanceVar);}public static void main(String[] args) {// 调用静态方法printStaticVar(); // 输出 "静态变量: 10"// 创建类的实例MethodComparison example = new MethodComparison();// 调用实例方法example.printInstanceVar(); // 输出 "实例变量: 20"}
}
在这个示例中:
printStaticVar
是一个静态方法,用于访问静态变量staticVar
。printInstanceVar
是一个实例方法,用于访问实例变量instanceVar
。- 在
main
方法中,我们直接调用了静态方法printStaticVar
,并通过类的实例调用了实例方法printInstanceVar
。
2.6 什么是抽象方法
2.6.1 抽象方法的特点
-
没有方法体:
- 抽象方法没有方法体,只有方法声明。抽象方法的声明以分号
;
结尾,而不是花括号{}
。
- 抽象方法没有方法体,只有方法声明。抽象方法的声明以分号
-
必须存在于抽象类中:
- 抽象方法必须在抽象类中声明。抽象类使用
abstract
关键字修饰。
- 抽象方法必须在抽象类中声明。抽象类使用
-
必须被重写:
- 当一个类继承了抽象类后,必须重写(实现)抽象类中的所有抽象方法。否则,子类也必须声明为抽象类。
2.6.2 抽象类的特点
-
不能实例化:
- 抽象类不能被实例化,只能被继承。抽象类可以包含抽象方法和非抽象方法。
-
可以包含成员变量和构造方法:
- 抽象类可以包含成员变量、构造方法和普通方法。
-
子类必须实现抽象方法:
- 如果一个类继承了抽象类,并且抽象类中有抽象方法,子类必须实现这些抽象方法。
2.6.3 示例代码
下面是一个示例,展示了如何声明和使用抽象方法和抽象类:
// 抽象类
abstract class AbstractDemo {// 抽象方法abstract void display();
}// 继承抽象类的子类
public class MyAbstractDemo extends AbstractDemo {// 重写抽象方法@Overridevoid display() {System.out.println("重写了抽象方法");}public static void main(String[] args) {// 创建子类的实例MyAbstractDemo myAbstractDemo = new MyAbstractDemo();// 调用重写的抽象方法myAbstractDemo.display(); // 输出 "重写了抽象方法"}
}
在这个示例中:
AbstractDemo
是一个抽象类,包含一个抽象方法display()
。MyAbstractDemo
类继承了AbstractDemo
类,并重写了display()
方法。- 在
main
方法中,我们创建了MyAbstractDemo
类的实例,并调用了重写的display()
方法。
3 思维导图
4 参考链接
- Java变量:了解局部变量、成员变量、静态变量和常量的特点与用途
- Java方法:实例方法、静态方法与抽象方法的区别与应用