我有一节课,Super
public class Super {
public static String foo = "foo";
}我还有另一个扩展Super的类Sub
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的内容会根据访问它的类的不同而不同。有谁能解释一下吗?
发布于 2012-03-28 05:40:21
我不明白为什么foo的内容会随着你访问它的类的不同而不同。
基本上这是一个类型初始化的问题。在初始化Sub时,foo的值被设置为"bar"。但是,在您的Testing类中,对Sub.foo的引用实际上被编译为对Super.foo的引用,因此它不会初始化Sub,因此foo永远不会变成"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);
}
}然后,它将打印"bar“四次,因为第一条语句将强制初始化Sub,这将更改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);
}
}这仍然会打印"foo“两次,显示Sub没有初始化--但它肯定是加载的,例如,如果您在运行Sub.class文件之前将其删除,程序将失败。
发布于 2016-03-17 07:14:27
在哪里更改静态变量的值并不重要,在Sub或Super中是相同的变量foo。无论您创建了多少new Sub或new Super对象,然后又进行了修改,这都无关紧要。这种变化随处可见,因为Super.foo、Sub.foo、obj.foo共享相同的storage.This,也适用于原始类型:
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来强调变量/方法的静态性质,并为编译器提供更好的优化机会。
发布于 2015-03-28 14:48:08
静态成员在java中不被继承,因为它们是类的属性,并且它们被加载到类区域中。它们与对象创建没有任何关系。但是,只有子类可以访问其父类的静态成员。
https://stackoverflow.com/questions/9898097
复制相似问题