我有一个班级Super
:
public class Super {
public static String foo = "foo";
}
我还有另一个类Sub
,它扩展了Super
:
public class Sub extends Super {
static {
foo = "bar";
}
public static void main (String[] args) {
System.out.println(Super.foo);
}
}
当我运行它时,会打印出bar
我的第三个(也是最后一个)课程是Testing
:
public class Testing {
public static void main (String[] args) {
System.out.println(Super.foo);
System.out.println(Sub.foo);
System.out.println(Super.foo);
}
}
打印:
foo
foo
foo
我不明白为什么foo
的内容会因您访问它的类而有所不同。谁能解释一下?
答案 0 :(得分:42)
我不明白为什么foo的内容取决于你从哪个班级访问它。
基本上这是类型初始化的问题。初始化foo
时,"bar"
的值设置为Sub
。但是,在Testing
课程中,对Sub.foo
的引用实际上已编译为对Super.foo
的引用,因此它不会最终初始化Sub
,因此{{1永远不会成为foo
。
如果您将测试代码更改为:
"bar"
然后它将打印出“bar”四次,因为第一个语句会强制public class Testing {
public static void main (String[] args) {
Sub.main(args);
System.out.println(Super.foo);
System.out.println(Sub.foo);
System.out.println(Super.foo);
}
}
被初始化,这会改变Sub
的值。这根本不是从哪里进入的。
请注意,这不仅仅是关于类加载 - 它是关于类初始化。可以在不初始化的情况下加载类。例如:
foo
仍然打印“foo”两次,显示public class Testing {
public static void main (String[] args) {
System.out.println(Super.foo);
System.out.println(Sub.class);
System.out.println(Super.foo);
}
}
未初始化 - 但它肯定是已加载,如果删除Sub
文件,程序将失败例如,在运行它之前。
答案 1 :(得分:0)
在哪里更改静态变量的值并不重要,它与Sub
或Super
中的变量foo相同。无论您创建并修改了多少new Sub
或new Super
个对象,都无关紧要。由于Super.foo
,Sub.foo
,obj.foo
共享相同的存储空间,因此随处可见此更改。这也适用于原始类型:
class StaticVariable{
public static void main(String[] args){
System.out.println("StaticParent.a = " + StaticParent.a);// a = 2
System.out.println("StaticChild.a = " + StaticChild.a);// a = 2
StaticParent sp = new StaticParent();
System.out.println("StaticParent sp = new StaticParent(); sp.a = " + sp.a);// a = 2
StaticChild sc = new StaticChild();
System.out.println(sc.a);// a = 5
System.out.println(sp.a);// a = 5
System.out.println(StaticParent.a);// a = 5
System.out.println(StaticChild.a);// a = 5
sp.increment();//result would be the same if we use StaticParent.increment(); or StaticChild.increment();
System.out.println(sp.a);// a = 6
System.out.println(sc.a);// a = 6
System.out.println(StaticParent.a);// a = 6
System.out.println(StaticChild.a);// a = 6
sc.increment();
System.out.println(sc.a);// a = 7
System.out.println(sp.a);// a = 7
System.out.println(StaticParent.a);// a = 7
System.out.println(StaticChild.a);// a = 7
}
}
class StaticParent{
static int a = 2;
static void increment(){
a++;
}
}
class StaticChild extends StaticParent{
static { a = 5;}
}
您可以通过对象(如sc.a
)或通过其类名(如StaticParent.a
)引用静态变量/方法。最好使用ClassName.staticVariable
来强调变量/方法的静态性质,并为编译器提供更好的优化机会。
答案 2 :(得分:-3)
静态成员不是在java中继承的,因为它们是类的属性,并且它们在类区域中加载。它们与对象创建无关。但是只有子类可以访问其父类的静态成员。