首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java对象分配是什么意思?

Java对象分配是什么意思?
EN

Stack Overflow用户
提问于 2015-04-28 20:59:17
回答 5查看 193关注 0票数 6

我有以下两门课:

代码语言:javascript
复制
class Animal {
    public static void staticMethod(int i) {
        System.out.println("Animal : static -- " + i);
    }

    public void instanceMethod(int i) {
        System.out.println("Animal : instance -- " + i);
    }
}

class Cat extends Animal {
    public static void staticMethod(int i) {
        System.out.println("Cat : static -- " + i);
    }

    public void instanceMethod(int i) {
        System.out.println("Cat : instance -- " + i);
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.staticMethod(1);                       // Cat : static -- 1
        myCat.instanceMethod(2);                     // Cat : instance -- 2
        System.out.println("");

        Animal myAnimal = myCat;
        Animal.staticMethod(3);                      // Animal : static -- 3 
        myAnimal.staticMethod(4);                    // Animal : static -- 4 [ ? ]
        System.out.println("");

        myAnimal.instanceMethod(5);                  // Cat : instance -- 5
    }
} 

当我运行Cat时,我得到了以下结果:

代码语言:javascript
复制
Cat : static -- 1
Cat : instance -- 2

Animal : static -- 3
Animal : static -- 4

Cat : instance -- 5

我能理解1,2,3和5,但为什么#4不是:“猫:静态-- 4”?我的理解是:

myAnimal=myCat的意思是" myAnimal“现在与" myCat”完全相同,所以在任何"myAnimal“词组中,您都可以用"myCat”替换它,得到相同的结果,因为myAnimal中的所有东西都与myCat中的所有东西相同,因此"myAnimal.staticMethod(4)“应该与"myCat.staticMethod(4)”相同,输出应该是:“猫:静态- 4",类似于上面的"myCat.staticMethod(1)”。

但情况似乎并非如此,为什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-04-28 21:10:14

来自Oracle文档

8.4.8.2.隐藏(通过类方法) 如果类C声明或继承了静态方法m,则说m隐藏了任何方法m',其中m的签名是m‘签名的子签名(§8.4.2),它位于C的超类和超级接口中,否则C中的代码可以访问。 例8.4.8.2-1。隐类方法的调用 可以通过引用调用隐藏的类(静态)方法,该引用的类型是实际包含方法声明的类。在这方面,隐藏静态方法与重写实例方法不同。例子:

代码语言:javascript
复制
class Super {
            static String greeting() { return "Goodnight"; }
            String name() { return "Richard"; }
        }
        class Sub extends Super {
            static String greeting() { return "Hello"; }
            String name() { return "Dick"; }
        }
        class Test {
            public static void main(String[] args) {
                Super s = new Sub();
                System.out.println(s.greeting() + ", " + s.name());
            }
        }

产生的输出: 晚安,迪克 因为问候语的调用使用s的类型,即Super,在编译时计算出要调用的类方法,而名称的调用使用s的类,即Sub,在运行时计算出要调用的实例方法。

票数 2
EN

Stack Overflow用户

发布于 2015-04-28 21:03:14

您可以声明myAnimalAnimal。因此,该类也调用了一个静态方法。

您不应该从实例中调用静态方法(或访问静态字段)来防止这种混乱。

票数 3
EN

Stack Overflow用户

发布于 2015-04-28 21:02:38

原因是Java基于引用变量本身的类型来解析静态方法,而不是像实例方法那样在运行时进行多态解析。

为了稍微扩展一下,在执行Animal myAnimal = myCat时,您要将一个猫引用分配给一个动物引用。这是可以接受的,因为Cat也是Animal,所以Animal可以做的任何事情,Cat也可以。

此外,如果您通过myAnimal引用调用一个实例(即非静态)方法,并且该方法在Cat中被覆盖,那么将调用该方法的Cat版本,因为这就是该方法首先被覆盖的原因。另一方面,静态方法永远不会被超越。这就是为什么它们是“静态”的,就像在“非动态”中一样。这意味着静态方法可以由编译器解析,而不必依赖运行时环境。

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

https://stackoverflow.com/questions/29929814

复制
相关文章

相似问题

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