private String name;//实例变量
private String id;
static String country = "中国";//静态变量
public static void main(String[] args//局部变量) {
int i = 0;//局部变量
}
静态与实例区别:
- 实例访问要new,静态访问用类名.
定义
static关键字:
- static修饰变量:静态变量
- static修饰方法:静态方法
- 所有static修饰的,在访问时间,直接采用”类名.“,不需要new对象。
- 什么情况下需要把成员变量定义为静态变量:当一个属性是对象级别,定义为实例变量;当一个属性是类级别(所有对象都有这个属性且属性值一样),建议定义为静态变量,因为在空间上只有一份,内存开销小。
- 静态方法中不能使用 this 关键字。因此无法直接访问实例变量和调用实例方法。
- 静态代码块在类加载时执行,一个类中可以编写多个静态代码块,遵循自上而下的顺序依次执行。
- 静态代码块代表了类加载时刻,如果你有代码需要在此时刻执行,可以将该代码放到静态代码块中。
代码
创建对象
package com.powernode.javase.oop_06;
public class User {
private String name;//实例变量
private String id;
static String country = "中国";//静态变量
public User(String name, String id) {
this.name = name;
this.id = id;
}
public void display(){
System.out.println(getName()+getId()+getCountry());
}
public static String getCountry() {
return country;
}
public static void setCountry(String country) {
User.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
调用对象
package com.powernode.javase.oop_06;
public class UserTest {
public static void main(String[] args) {
User u = new User("小白","123456");
u.display();
User u2 = new User("小黑","123789");
u2.display();
System.out.println("国籍"+User.country);
}
}
运行结果
C:\Users\seven\.jdks\corretto-1.8.0_362\bin\java.exe -javaagent:D:\IDEAIU\lib\idea_rt.jar=63663:D:\IDEAIU\bin -Dfile.encoding=UTF-8 -classpath C:\Users\seven\.jdks\corretto-
小白123456中国
小黑123789中国
国际中国
Process finished with exit code 0
内存图对比
实例变量
含静态变量
空指针异常
package com.powernode.javase.oop_06;
public class UserTest {
public static void main(String[] args) {
User u = new User("小白","123456");
u.display();
//静态变量使用引用.去调用,会报错。
System.out.println(u.country);
u = null;
//静态变量可以使用引用.去调用,但实际运行与对象无关
//以下程序不会出现空指针异常
System.out.println(u.country);
//一个空引用访问实例变量相关的,都会出现空指针异常
//System.out.println(u.name);
}
}
实例方法与静态方法互相访问
实例访问静态
package com.powernode.javase.oop_06;
public class User2 {
int a = 10;//实例变量
static int b = 11;//静态变量
//实例方法
public void c(){
System.out.println(this.a);
System.out.println(User2.b);
this.c();//方法递归
User2.d();
//简写版本
System.out.println(a);
System.out.println(b);
c();
d();
}
//静态方法
public static void d(){
}
}
静态访问实例
🔔如果想要在static中使用实例变量/方法,可以在静态方法里面new一个 。
package com.powernode.javase.oop_06;
public class User2 {
int a = 10;//实例变量
static int b = 11;//静态变量
//静态方法
public static void d(){
//访问静态
System.out.println(User2.b);
User2.d();
//访问实例
User2 u = new User2();
System.out.println(u.a);
u.c();
//不可以出现this,及时在同一个类下面
//报错System.out.println(this.a);
}
//实例方法
public void c(){
}
}
静态代码块
- 区别于构造代码块:构造代码块创建对象时候,调用一次构造代码块
- 静态代码块什么时候执行?执行几次?:在类加载时间执行,且只执行一次。
- 什么时候用:本质上静态代码块就是为程序员预留一个特殊时间节点(类加载时刻);如果要做类加载时刻执行一段程序的话,这段代码可以写在静态代码块里面;例如要在类加载时,记录日志的需求。
package com.powernode.javase.oop_06;
public class StaticTest {
String name = "小白";
static int a = 1;
static {
//报错:System.out.println(name);
//静态上下文无法直接访问实例变量
System.out.println("静态代码块执行了");
System.out.println(a);
//报错:System.out.println(b);
//为什么a可以,而b不可以:因为静态代码块是在类加载的时候执行的,a b 也是静态变量,在类加载时就要按顺序执行,所有b报错
}
static int b = 2;
}