首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中规定静态变量继承的规则是什么?

在Java中规定静态变量继承的规则是什么?
EN

Stack Overflow用户
提问于 2012-03-28 05:37:22
回答 3查看 37.6K关注 0票数 47

我有一节课,Super

代码语言:javascript
复制
public class Super {
    public static String foo = "foo";
}

我还有另一个扩展Super的类Sub

代码语言:javascript
复制
public class Sub extends Super {
    static {
        foo = "bar";
    }

    public static void main (String[] args) {
        System.out.println(Super.foo);
    }
}

当我运行它时,它会打印出bar

我的第三个(也是最后一个)类是Testing

代码语言:javascript
复制
public class Testing {
    public static void main (String[] args) {
        System.out.println(Super.foo);
        System.out.println(Sub.foo);
        System.out.println(Super.foo);
    }
}

这将打印:

代码语言:javascript
复制
foo
foo
foo

我不明白为什么foo的内容会根据访问它的类的不同而不同。有谁能解释一下吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-28 05:40:21

我不明白为什么foo的内容会随着你访问它的类的不同而不同。

基本上这是一个类型初始化的问题。在初始化Sub时,foo的值被设置为"bar"。但是,在您的Testing类中,对Sub.foo的引用实际上被编译为对Super.foo的引用,因此它不会初始化Sub,因此foo永远不会变成"bar"

如果您将测试代码更改为:

代码语言:javascript
复制
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的值。这根本不是从哪里访问它的问题。

请注意,这不仅仅与类加载有关-它还与类初始化有关。类可以在不初始化的情况下加载。例如:

代码语言:javascript
复制
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文件之前将其删除,程序将失败。

票数 43
EN

Stack Overflow用户

发布于 2016-03-17 07:14:27

在哪里更改静态变量的值并不重要,在SubSuper中是相同的变量foo。无论您创建了多少new Subnew Super对象,然后又进行了修改,这都无关紧要。这种变化随处可见,因为Super.fooSub.fooobj.foo共享相同的storage.This,也适用于原始类型:

代码语言:javascript
复制
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来强调变量/方法的静态性质,并为编译器提供更好的优化机会。

票数 0
EN

Stack Overflow用户

发布于 2015-03-28 14:48:08

静态成员在java中不被继承,因为它们是类的属性,并且它们被加载到类区域中。它们与对象创建没有任何关系。但是,只有子类可以访问其父类的静态成员。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9898097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档