我是 ABin-阿斌:写一生代码,创一世佳话。 如果小伙伴们觉得我的文章有点 feel ,那就点个赞再走哦。
Static关键字的诞生原因:
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。
有什么特点:
static 是一个修饰符,静态的。主要用来修饰类的内部结构,分为四大类:属性、方法、代码块、内部类。
修饰属性(静态变量或类变量)
- 没有被 Static 修饰的属性我们一般称为:非静态属性(就是我们的实例变量)
- 实例变量: 当我们在一个类中创建了多个对象时,我们每一个对象都独立拥有着一个类中的非静态属性。当我们对这个属性更改时,那么其他对象中的属性不会受我们影响。
- 被 Static 修饰的属性我们称为:静态属性
- 静态变量: 我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他调用了此静态变量都发生修改。
修饰属性的其它特点说明:
- 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
- 静态变量的加载要早于对象的创建。
- 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
静态变量内存解析:
修饰方法(静态方法、类方法)
- 随着类的加载而加载,可以通过(类 . 静态方法)的方式进行调用
- 静态方法中,只能调用静态的方法或属性。非静态的方法和属性必须依赖于对象才能被调用,否则编译不通过。
- 非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
声明:
- 关于内部类和代码块的使用后期会专门写一篇(类结构的介绍与使用文章),到时候大家点这个链接就可以了Java基础:面向对象:类的结构的介绍与使用
Static的注意事项:
在静态方法中 不能使用(this关键字、super关键字)
原因:
- this 代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后,对象还不一定存在。
- super 的用法跟 this 类似,this 代表对本类对象的引用,指向本类已经创建的对象。而 super 代表对父类对象的引用,指向父类对象。静态优先于对象存在。因为它是随着类的加载而加载的,所以方法被静态修饰之后方法先存在,而方法里面要用到 super 指向的父类对象,但是所需的父类引用对象晚于该方法出现,也就是 supe r所指向的对象没有,当然就会出错。
如何去判断属性和方法应该使用 Static 关键字:
关于属性
- 在实际开发当中,我们这个属性是可以被多个对象所共享的,不会随着对象的不同而改变的。那么这个时候我们就可以考虑用静态(Static)去修饰它了。
- 类中的常量也常常声明为static
关于方法
- 操作静态属性的方法,通常设置为 static 的
- 工具类中的方法,习惯上声明为 static 的。 比如:Math、Arrays、Collections,大家可以进入到源码一看就知道了。
代码演示
/**
* 测试
*/
public class StaticTest {
public static void main(String[] args) {
//通过类直接调用静态属性
Chinese.nation = "中国";
Chinese c1 = new Chinese();
c1.name = "马云";
c1.age = 40;
c1.nation = "CHN";
Chinese c2 = new Chinese();
c2.name = "马化腾";
c2.age = 30;
c2.nation = "CHINA";
//此时输出 CHINA,原因:请看上方--静态变量
System.out.println(c1.nation);
//编译不通过:非静态属性不能用类.去调用
// Chinese.name = "刘强东";
c1.eat();
Chinese.show();
//编译不通过
// Chinese.eat();
// Chinese.info();
}
}
//中国人
class Chinese{
String name;
int age;
static String nation;
public void eat(){
System.out.println("中国人吃中餐");
//调用非静态结构
this.info();
System.out.println("name :" +name);
//调用静态结构
walk();
System.out.println("nation : " + nation);
}
public static void show(){
System.out.println("我是一个中国人!");
//不能调用非静态的结构
// eat();
// name = "Tom";
//可以调用静态的结构
System.out.println(Chinese.nation);
walk();
}
public void info(){
System.out.println("name :" + name +",age : " + age);
}
public static void walk(){
}
}