static关键字
程序引例
/*
定义一个人的类
经过测试发现,我们举例子的时候,都是中国人,国籍都一样,都是中国
一样的国籍,每次创建的时候,都会在堆内存开辟一个这样的变量空间
总觉得有点浪费。
有没有什么办法,让所有一样国籍的人共用一个国籍的值
针对多个对象拥有共同的成员变量,值是一样的时候
Java提供了一个关键字给我们处理这样的情况,这个关键字叫做:static
可以修饰成员变量和成员方法,修饰成员变量的时候,可以让多个对象共用一个成员变量的值。
*/
class Person{
//姓名
private String name;
//年龄
private int age;
//国籍
// private String nationality;
private static String nationality;
public Person() {
}
public Person(String name, int age, String nationality) {
this.name = name;
this.age = age;
this.nationality = nationality;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public void show(){
System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+nationality);
}
}
public class PersonDemo {
public static void main(String[] args) {
//创建第一个对象
Person p1 = new Person("宋轶",26,"中国");
p1.show();
//创建第二个对象
Person p2 = new Person("胡歌",30);
p2.show();
//创建第三个对象
Person p3 = new Person("钱学森",18);
p3.show();
System.out.println("==========================================");
p1.setNationality("俄罗斯");
p1.show();
p2.show();
p3.show();
}
}
程序引例过程内存图解
static的特点:
它可以修饰成员变量和成员方法
- 随着类的加载而加载
运行之前会将class类文件加载到方法区中,而被static修饰的成员是随着类的加载而加载,所以被static修饰的成员在方法区存放。(例如:main方法)
- 优先于对象存在
- 被类所有的对象共享
举例:所有的中国人的国籍信息都一样
什么时候使用static关键字呢?如果说明某个成员变量是被所有对象共享的,那么它就应该被定义为静态的。举例:哈罗单车:(可以被static修饰)自己的水杯:(不可以被static修饰)
- 被静态修饰的成员可以直接通过类名调用
一般情况下,我们今后开发的时候,只要看到类中有静态的成员变量或者成员方法今后调用的时候,一律用 类名.静态成员 这样的方式去调用
推荐使用类名的方式调用,这也是规范。通过调用的方式不同区分不同的成员
所以被静态修饰的成员,一般情况下被称之为:类成员,与类相关的
程序示例
class Demo2{
//定义一个非静态的成员变量
int a = 10;
//定义一个静态的成员变量
static int b = 20;
}
public class StaticDemo1 {
public static void main(String[] args) {
// Demo2 d1 = new Demo2();
// System.out.println(d1.a);
// System.out.println(d1.b);
System.out.println(Demo2.b);
}
}
static关键字注意事项
- 在静态方法中是没有this关键字的(因为static是属于类的,随着类的加载而加载的,优先于对象存在。this是创建对象的时候出现的,所以被static修饰的方法里面不能有this)
- 静态方法只能访问静态的成员变量和静态的成员方法
程序示例
/*
静态成员访问的问题:
1、static可以修饰成员变量和成员方法
2、
非静态的成员方法:
1)访问的是非静态的成员变量
可以
2)访问的是静态的成员变量
可以
3)访问的是非静态的成员方法
可以
4)访问的是静态的成员方法
可以
总结:非静态的成员方法可以访问静态的成员也可也访问非静态的成员
静态的成员方法:
1)访问的是非静态的成员变量
不可以
2)访问的是静态的成员变量
可以
3)访问的是非静态的成员方法
不可以
4)访问的是静态的成员方法
可以
总结:静态的成员方法只能访问静态的成员
*/
class Demo3{
//非静态的成员变量
int a = 10;
//静态的成员变量
static int b = 20;
//非静态的成员方法
public void fun1(){
System.out.println(a);
System.out.println(b);
fun2();
fun3();
}
public static void fun2(){
//Error:(47, 28) java: 无法从静态上下文中引用非静态 变量 a
// System.out.println(a);
// System.out.println(b);
// System.out.println("这是静态的成员方法fun2");
//Error:(51, 9) java: 无法从静态上下文中引用非静态 方法 fun3()
// fun3();
fun4();
}
public void fun3(){
System.out.println("这个是非静态的成员方法fun3");
}
public static void fun4(){
System.out.println("这是静态的成员方法fun4");
}
}
public class StaticDemo2 {
public static void main(String[] args) {
Demo3 d = new Demo3();
// d.fun1();
Demo3.fun2();
fun();
}
public static void fun(){
System.out.println("helloworld");
}
}