Static变量的总结
1.不可从一个static方法内部发出对非static方法的调用,尽管反过来说是可以的。如果要在static方法中访问所在类的成员变量或方法,就必须首先创建相应的实例变量。
2.static变量可以通过类名直接访问,
3.static方法不能被覆盖,但是在子类中可以声明与父类惊天方法相同的方法,从而将父类的静态方法隐藏,另外自乐不能把父类的非静态方法重写为静态的:并且static方法也不能够重载(因为他们是前期绑定的,所以不能重载;不能重载的方的还有final、private)
而普通方法能被覆盖,覆盖的结果是产生多态;
例子:
package test;
class Test {
public static void main(String[] args) {
A a = new B();
a.f();
a.m();
}
}
class A {
public static void f() {
System.out.println("hello,A");
}
public void m() {
System.out.println("hello,A");
}
}
class B extends A {
public static void f() {
System.out.println("hello,B");
}
public void m() {
System.out.println("hello,B");
}
}
结果是:
hello,A
hello,B
1.根据Java Language Specification (Version 3) 8.4.8 的描述,子类在继承父类时,对于方法而言,存在两种关系:
A. override 即覆盖,这是对实例方法(instance method)而言的;子类与父类中形构相同的方法(原文中是 subsignature,它的范围比“形构相同”要大,请参考原文)会override 父类中的那个方法。
B. hide 即隐藏,这是对类方法(class method)即static 方法而言的。如果子类中定义了静态方法,则它会隐藏父类中形构相同的(原文中是 subsignature,它的范围比“形构相同要”大,请参考原文)所有方法,但如果隐藏了父类中的实例方法,则会编译报错。
2.根据上面的规范:
“override 覆盖”的前提是实例方法,只有实例方法在继承时才会出现override情况。
如果是static方法,在继承时出现的现象根本就不能用“override”这个词描述,如果static方法在父类和子类中形构一致,则被成为 hide(隐藏)。
3.因为static方法是类方法,实现时是静态绑定的(引用“JAVA 核心技术 卷1 第六版”中149页内容“private、static、final”修饰的方法是静态绑定的。其他的方法在运行时动态绑定。“interhanchi”所说的“static和final方法外都是后期绑定”并不精确),只与类相关,不会有多态性。 从编程的角度看,效果好像是“static方法不能被覆盖”;
4.从术语上看,“static方法能否被覆盖”这种说法本身就是错误的,因为“覆盖”定义的前提和基础是实例方法。
5.结论: 子类中的static方法会隐藏父类中形构相同的static方法。
final变量的总结:
Final不想做改变的理由是:设计和效率
在java中除了static方法、final方法、(private方法属于final方法)之外,其他所有的方法都是后期绑定
Final可以修饰基本类型,也可以修饰引用类型,但是当final修饰引用类型的时候,不能够改变引用指向另一个对象, 但这个对象本身的状态是可以改变的...
final String string=“final”;
是开辟了2个内存空间,在栈中的string引用在堆中的final,其中string是始终指向堆中的final这个地址的引用,不能改变。但是堆中的final却可以改变。
可以通过下面的例子来说明static final的作用:
public class Test0
{
private static final String string;
public Test0(String str)
{
string=str;
System.out.println(string);
}
public static void main(String[] args)
{
Test0 t=new Test0("hello world");
Test0 tt=new Test0("world hello");
}
}
解释说明:
1.首先正确的认识一下final, 一个final修饰的叫"终态", 而这种终态很特殊, 它指的是:"当这个变量被赋值之后成为终态". 那么,当一个被赋值之后的final修饰变量, 将不可再被赋新值. (先理解)
2.而static表示静态变量, 说穿了,你需要知道JAVA如何为一个类创建内存空间--我们知道类有空间,类产生的实例(对象)有空间,方法有空间,变量有空间, 当static修饰时, 这个变量会在类分配内存时就被分配内存了, 所以你知道,你可以不用产生对象就使用静态变量.
3.好了,有了以上两点,我们来看看, 你可以根据我的叙述试试. 首先,你只使用final修饰你的string, 你会发现不会报错, 因为这是一个"还没有被赋值的非静态的终态变量(在类分配内存时不会分配内存).好,接下来你改一下,写:private final String string = "sss"; 你会发现报错了,原因自己想.
接下来, 看你发出来的代码, 又被static修饰,又被final修饰,首先它是一个静态变量, 那么在类分配时就会分配内存, 实际上这个String就被初始化了,既然初始化了, 那么也就有值了, 而一个终态被赋值变量将不能再被赋值, 那么自然就报错了