文章目录
- 一、静态变量
- 特点
- 调用方式
- 二、静态方法
- 特点
- 调用方式
- 三、类的类型
- 1.Javabean类
- 2.测试类
- 3.工具类
- 四、注意事项
- 从代码方面解释
- 1. 上下文清晰
- 2. 静态变量的访问
- 例子
- 注意
- 3. 静态方法中没有`this`关键字
- 原因
- 4. 静态方法只能访问静态变量和静态方法
- 错误原因
- 解决方法
- 4.非静态方法可以访问所有
- 从内存方面解释
- 1.静态方法只能访问静态,不能访问非静态
- 2.非静态方法可以访问所有
- 重新认识main方法
- IDRE2024中`args`数组使用方法
一、静态变量
被static修饰的成员变量:
public static String teacherName;
特点
- 被该类所有对象共享
- 不属于对象,属于类
- 随着类的加载而加载,优先于对象存在
调用方式
- 类名调用(推荐)
- 对象名调用
二、静态方法
被static修饰的成员方法:
public static void method(){ System.out.println("静态方法"); }
特点
- 多用在测试类和工具类中
- Javabean类中很少会用
调用方式
- 类名调用(推荐)
- 对象名调用
三、类的类型
1.Javabean类
用来描述一类事物的类。比如,Student,Teacher等
2.测试类
用来检查其他类是否书写正确,带有main方法的类,是程序的入口
3.工具类
帮助我们做一些事情的,但是不描述任何事物的类
-
类名见名知意
-
私有化构造方法(不让外界创建对象,因为没意义)
-
方法定义为静态
四、注意事项
- 静态方法中没有
this
关键字- 静态方法只能访问静态变量和静态方法
- 非静态方法可以访问所有
解释:
Student.java
public class Student {
String name;
int age;
static String teacherName;
public void show1(){
System.out.println(name+","+age+","+teacherName);
show2();
}
public void show2(){
System.out.println("show2");
}
public static void method(){
System.out.println("静态方法");
}
}
Student.java中非静态方法:
public void show1(){
System.out.println(name+","+age+","+teacherName);
show2();
}
其实省略了this:
public void show1(Student this){
System.out.println(this.name+","+this.age+","+teacherName);
this.show2();
}
this
表示当前方法使用者的地址值,是由虚拟机赋值的
在 Java 中,this
关键字用于引用当前对象的实例。然而,在方法内部,当你访问实例变量或实例方法时,可以省略 this
,因为 Java 默认会将没有明确指定的变量解析为当前对象的属性。
从代码方面解释
1. 上下文清晰
在实例方法中,编译器能够推断出访问的变量是当前对象的属性,因此在大多数情况下,你可以省略 this
。
例如:
public void show1() {
System.out.println(name + "," + age + "," + teacherName);
}
在这个方法中,name
和 age
被认为是当前对象的属性,因此你可以直接使用它们而不需要 this.name
和 this.age
。
2. 静态变量的访问
对于静态变量(如 teacherName
),因为它属于类本身而不是类的实例,所以在静态上下文中访问时,你可以直接使用类名来访问它(如 Student.teacherName
),但在实例方法中也可以直接使用 teacherName
,或者使用this.teacherName
也行,因为它同样可在所有实例间共享。
例子
考虑下面这个示例,展示了如何省略 this
:
public class Student {
String name;
int age;
static String teacherName;
public void show1() {
System.out.println(name + ", " + age + ", " + teacherName);
}
}
注意
- 当局部变量与实例变量同名时,必须使用
this
来消除歧义。例如:
public void setName(String name) {
this.name = name; // 使用 this 来区分实例变量和参数
}
总的来说,this
可以省略是因为 Java 的设计使得在实例方法中,访问当前对象的属性和方法时可以清晰且简洁。
3. 静态方法中没有this
关键字
public static void method(){
System.out.println("静态方法");
}
不能写成:
public static void method(Student this){
System.out.println("静态方法");
}
原因
- 静态方法不需要 this 关键字,因为它们不依赖于任何特定对象的状态。this 只在实例方法中有效,用于引用当前对象,而静态方法是类级别的方法,不涉及任何对象的实例。因此,在静态方法中,不能使用 this 关键字或将其作为参数。静态方法可以通过类名直接调用,而不需要创建类的实例。例如:
Student.method()
。
4. 静态方法只能访问静态变量和静态方法
public static void method(){
System.out.println(name);
show1();
System.out.println("静态方法");
}
上述代码会报错
错误原因
- 静态方法不能访问实例变量(对象的属性)或实例方法(非静态方法),因为它没有
this
指针来引用当前对象。
public static void method() {
System.out.println(name); // 访问实例变量,报错
show1(); // 调用实例方法,报错
System.out.println("静态方法");
}
-
System.out.println(name);
这一行会报错,因为name
是实例变量,静态方法无法直接访问它。编译器无法找到name
的上下文,因为没有this
指针指向任何实例。 -
show1();
这一行也会报错,因为show1()
是实例方法,同样静态方法无法调用实例方法。你必须创建该类的一个实例才能调用实例方法。
解决方法
如果你希望在静态方法中访问实例变量或实例方法,必须先创建该类的一个对象。例如:
public static void method() {
Student student = new Student(); // 创建 Student 类的实例
System.out.println(student.name); // 通过实例访问实例变量
student.show1(); // 通过实例调用实例方法
System.out.println("静态方法");
}
4.非静态方法可以访问所有
public class Student {
String name;
int age;
static String teacherName;
public void show1() {
System.out.println(name + ", " + age + ", " + teacherName);
}
method();
}
中teacherName
为静态变量,method()
为静态方法,代码不会出错。
原因:非静态方法中有this
指针引用当前对象,我们知道静态变量和静态方法的调用方式用两种,分别是用类名调用和用对象名调用,上述代码其实省略了this
,如下:
public class Student {
String name;
int age;
static String teacherName;
public void show1(Student this) {
System.out.println(this.name + ", " + this.age + ", " + this.teacherName);
}
this.method();
}
而且静态方法和静态变量是共享的。
从内存方面解释
- 静态:随着类的加载而加载
- 非静态:跟对象有关的
- 只要没创建对象,非静态的数据就不会进入到内存当中
1.静态方法只能访问静态,不能访问非静态
-
main方法进栈
-
执行下一行代码,
Student
类被使用,Student
的字节码文件Student.class
被加载到方法区,里面会有所有的成员变量和成员方法,JDK7以前不管是静态的还是非静态的都在方法区,JDK7以后会把静态变量移到堆中,称为静态区。static String teacherName
进入静态区并且赋值,未赋值前默认为null
。 -
执行下一行代码,在方法区中找到方法
method()
,将方法加载到栈内存中,该方法需调用非静态变量name
和静态变量teacherName
,静态变量teacherName
在静态区中能找到,而非静态变量name
由于没有对象在堆内存中,在堆内存中找不到。 -
因此,静态方法不能调用非静态成员变量(或者称为实例变量)
-
静态方法中的非静态show()方法没有对象指明,无法调用。倘若能调用,没有对象,也就没有地方调用变量,因此静态方法不能调用非静态方法
2.非静态方法可以访问所有
- s1属于Student类,因此它既可以通过对象名调用静态变量
teacherName
,也可以通过类名调用静态变量teacherName
,同样,它也可将静态方法method()
从方法区加载到栈中 - 非静态方法和非静态变量可以通过对象名调用
- 因此,非静态方法可以访问所有
重新认识main方法
IDRE2024中args
数组使用方法
public static void main(String[] args){
System.out.println(args[0]);
System.out.println(args[1]);
}
输入数据并点击运行:
结果:
注意:args
数组是一个字符串数组,从键盘输入的数据都是字符串,若要用其它类型需要进行转换,如整型:
public static void main(String[] args){
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
int min;
if(x<y) min=x;
else min=y;
System.out.print(min);
}
double
型:
double x=Double.parseDouble(args[0]);
double y=Double.parseDouble(args[1]);
float
型:
float x=Float.parseFloat(args[0]);
float y=Float.parseFloat(args[1]);