文章目录
前言
static关键字,一看见static关键字,就要本能的想到被static修饰的东西一定的对象无关,有的语言中也把static叫做静态,表示共有的含义
一、static可以修饰哪些东西?
二、static修饰属性
static修饰的属性称为类属性,类变量,所有对象共享
1.为什么要引入static?
public class StaticTest{
Person per2 = new Person();
per2.name = "小泉";
per2.age = 50;
Preson.country = "小日本";
Person per1 = new Person();
per1.name = "张三";
per1.age = 18;
Person.country = "中国";
per1.show();
per2.show();
}
class Person[
String name;
int age;
static String country = "中国";
void show(){
System.out.println("姓名为:" + name + ",年龄为:" + age + ",国籍为:" + country)
}
]
//输出结果
//姓名为:张三,年龄为:18,国籍为:中国
//姓名为:小泉,年龄为:50,国籍为:中国
1.看到上面的代码,我们会看到,per2这个对象的国籍输出本来应该为“小日本”,但是输出却为“中国”,这是怎么回事呢?这是因为country这属性是被“static”关键字修饰的属性,一个成员属性一旦被static修饰,他就表示类的属性,就会被存入JVM的方法区中,被该类的所有对象共享此属性,所有对象的属性值都一样;而且很多对象可能是同一个值,比如中国人的所有对象的country都是中国,如果不用static修饰,那么每个对象都在堆中保存自己的country属性,会占用很多的空间。
2.而且被static修饰的属性,被任意一个对象所修改之后,对于该类中所有的对象都是可见的,被其中一个对象修改了值,那么所有对象的此属性都为修改后的值(牵一发而动全身)。
3.static修饰的属性,直接通过类名称就可以访问,无需通过对象访问。
例如country被static修饰就可以直接通过Person访问
Person.country
内存图
调用new Person()来产生Person对象,首先要有Person这个类才能产生对象,首先要将Person类加载到内存中,Person类中的所有static变量就会被加载到方法区中
方法区中存放类中的所有方法,常量,静态变量
在Java中,在一个方法的内部是不能定义一个static变量的,因为方法中定义的变量全部都是局部变量,局部变量保存在栈中,而静态变量保存在方法区中,局部变量出了方法区就会被栈回收,而静态变量不会,所以局部变量前不能加static
2.final和static的区别
class Persong{
//成员常量,在堆中存储
final age = 10;
//静态变量。在方法区中存储
sattic String country = "中国";
}
1.finnal修饰的属性不可以被改变,所以被赋值之后就是一个常量,但还是成员属性,在堆中存储
2.static修饰的属性,被称为静态变量,在方法区中存储,所有的Person的对象共享这个属性
3.一旦在类中定义了一个常量(定义时就要赋值或者在构造方法中赋值),那么类中的所有对象的这个属性值都是一样的,那我们就可以使用static和final共同修饰这个属性,把他放在方法区中,让该类的的所有对象共享此属性,这样比较节省空间
4.全局常量,就是用static final共同修饰,常量的命名规则:所有单词全部大写,多个单词使用下划线分隔
3.修饰属性总结
1.static变量称为类属性,在方法区中存储,该类的所有对象共享此属性
2,若在类中定义了常量(定义时赋值或在构造方法中赋值),一般使用static和final共同修饰,称为全局常量
3.要使用类属性,我们通常使用类名称.属性名称,不推荐使用对象调用类属性,不规范。
3.1不产生对象可以直接通过类名称调用static属性吗?—> 可以
public class StaticTest{
Person per = null;
//不产生对象也能直接通过类名称调用
System.out.println(Person.country)
//static属性称为类属性,没有对象也可以直接通过类名称调用(包括该类的null引用)
System.out.println(per.country)
}
class Person[
String name;
int age;
static String country = "中国";
void show(){
System.out.println("姓名为:" + name + ",年龄为:" + age + ",国籍为:" + country)
}
]
//结果
//中国
//中国
NullPointerException —> 空指针异常,一定是使用了一个值为null的引用取访问了属性或者方法,
这里指的一定是成员属性和成员方法
,而和静态属性和静态方法无关
二、static修饰方法
static修饰方法称为类方法,工具方法,静态方法,通过类名称直接访问,没有对象也能访问
2.1为什么主方法是静态方法?
主方法就是一个被static修饰的方法
主方法是一个程序的入口,如果主方法是成员方法,那就得通过对象来调用,此时没有入口,就产生不了对象
程序从主方法开始执行,主方法要能调用起来,就得是静态方法,直接调用,无需产生对象
2.2静态方法能否访问成员方法和成员属性
我们缕一缕其中的逻辑,静态方法是没有对象就可以调用,而成员方法和成员属性必须要有对象才能调用,这就产生了矛盾,记住一条结论
结论:在静态方法中只能调用静态属性和静态方法,static家族之间可以互相调用,不能直接调用成员变量和成员方法,必须通过对象调用。
2.3成员方法能否访问静态方法和静态属性
成员方法必须通过对象来调用,能用成员方法说明已经产生了对象,静态方法和静态变量无需对象就能调用,更何况现在已经产生了对象
结论:在成员方法中既可以调用成员方法,也可以调用静态方法。
三、static修饰代码块
static修饰代码块称为静态代码块,在类加载时执行一次
主类中的静态块优先于主方法执行,JVM执行主方法,首先得加载主类,主类一加载,静态块就执行了