背景
我学习java时候学习笔记,对于初学java的人思路更接近一,希望能帮助刚接触java的同学。现在看当时的笔记实在乱的可以,工作这么多年业成长了很多
黄金原则
被static修饰的方法和属性在类被载入时(是否new对象无关)就已经被分配了内存。
和普通方法属性相比,他们可以通过两种方法访问。
1,直接访问:类名.属性名
2,实例化后访问:对象名.属性名
因为静态属性不属于某个对象,是类属性,所以推荐使用直接访问的方式。
黄金原则:static修饰的,属于类,为所有对象共有。
在对象创建之前就已存在。不能调用任何非静态的属性和方法。
修饰三个内容
static关键字可以用来修饰下面三个内容
修饰属性
-所有成员共享,类变量
修饰方法
-不需要实例化,可以直接访问
-静态方法只能访问静态成员,不能直接访问非静态成员
-静态方法不能使用this,super关键字
-静态方法不能被重写(隐藏),不具备多态特性,不能修饰构造器。
修饰代码块
-由static修饰的,不包含在任何方法体中的代码块
-当类被载入时,静态代码块被执行,且只被执行一次。而普通代码块将被执行3次。
public class TestStatic {
//静态代码块
static{
System.out.println("静态方法");
}
//动态代码块
{
System.out.println("动态方法");
}
public static void main(String[] args) {
TestStatic ts1 = new TestStatic();
TestStatic ts2 = new TestStatic();
TestStatic ts3 = new TestStatic();
// 静态方法 只执行一次
// 动态方法 执行三遍
// 动态方法 执行三遍
// 动态方法 执行三遍
}
}
QA
解析:为什么静态代码块只执行了一次
静态代码块内存,是在new对象之前就已经存在,不管创建多少对象都只会共享该方法快。
而非静态代码块,存放在heap内存,每当new一个对象的时候,该内存就会被执行一次。
QA1:为什么static只能修饰成员变量,不能修饰局部变量
C++里面可以这么做,而java里面不能这么做,主要因为没有这个必要。
成员变量是类的变量,局部变量是方法的变量。局部变量是有生命周期的,在其方法调用完后就会从statc内存中释放,回收资源。如果被定义成为static,就没办法回收这块内存了。
static修饰的成员变量属于类共享的,而不是某个方法。所以概念上来讲,static修饰的变量也就是成员变量。
QA2:为什么static不能用this,super关键字,非静态成员
this指的是当前对象的引用,当前对象在new的时候才被存放在Heap内存中。而static修饰的属性方法在对象创建之前(加载类时)就已经存在。也就是说static内存是优先于heap的,系统在给static分配内存时候,this所指向的对象还不存在。super,非静态成员原理同this。
QA3,static 方法不能被重写(只有非静态方法存在重写)
package Static;
class A {
public static void a() {
System.out.println(“a”);
}
//静态方法会被子类继承
public static void t() {
System.out.println("t");
}
}
class B extends A {
public static void a() {
System.out.println(“b”);
}
}
//子类B并未重载父类的方法,也没实现多态
public class Test {
public static void main(String[] args) {
A a = new B();
a.a();// 输出结果是a
B b = new B();
b.a();//输出b,b可以调用自身方法
B.t();//子类继承了父类的静态方法
// B.a();//静态属性不属于某一个对象,使用方法为 类名.属性名。
}
}
静态的方法可以被继承,但是不能重写。
Java中,如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。
结尾
正如同《Java编程思想》中所说:“一旦你了解了多态机制,可能就会认为所有事物都可以多态地发生。然而,只有普通方法的调用可以是多态的。”这也很好地理解了,为什么在Java中,static方法和final方法(private方法属于final方法)是前期绑定,而其他所有的方法都是后期绑定了。
java不推荐用对象调用static方法,这会使人混淆,请大家注意。
这也是为什么abstract修饰的method是不可同时是static的原因:
abstract修饰方法,子类需要重写去实现,主要用于各个子类的实例对象;
static修饰方法,则方法不属于某个对象,属于class,可用class名.方法名(),进行调用;
简单的说abstract实例对象,而static属于类,所以static方法不能是abstract方法。