Java 在子类的对象上调用direct时的静态和私有方法行为听起来像是重写?

Java 在子类的对象上调用direct时的静态和私有方法行为听起来像是重写?,java,static,private,overriding,access-specifier,Java,Static,Private,Overriding,Access Specifier,在R&D中,我在privateMethod()的情况下发现了这个方法-因为这个方法在子类的对象上不可用,所以子类和父类的privateMethod()是单独的方法,它们没有关系,所以这不是重写。 但在staticMethod()的情况下-父类的方法在子类的对象上可用,当我们在子类中定义此方法时,子类的对象开始指向子类方法。这看起来像方法重写,但不是,因为静态方法不重写。 java开发工具包如何处理静态方法 public class B extends A{ public static

在R&D中,我在privateMethod()的情况下发现了这个方法-因为这个方法在子类的对象上不可用,所以子类和父类的privateMethod()是单独的方法,它们没有关系,所以这不是重写。 但在staticMethod()的情况下-父类的方法在子类的对象上可用,当我们在子类中定义此方法时,子类的对象开始指向子类方法。这看起来像方法重写,但不是,因为静态方法不重写。

java开发工具包如何处理静态方法

public class B extends A{

    public static void main(String[] args) {
    new B().privateMethod();//no error -output B-privateMethod.Sounds like overriding
    new B().staticMethod(); //no error -output B-StaticMethod.Sounds like overriding
    }

    private void privateMethod() {
        System.out.println("B-privateMethod.");
    }
    static void staticMethod() {
        System.out.println("B-StaticMethod.");
    }
}


class A{
    private void privateMethod() {
        System.out.println("A-privateMethod.");
    }
    static void staticMethod() {
        System.out.println("A-StaticMethod.");
    }
}
这不是重写,因为B没有看到A的privateMethod()

这不是重写,允许通过实例调用静态方法,尽管这可能会让人困惑。它与通过类名调用它完全相同-
B.staticMethod()
。如果
B
的超类
a
有一个从
B
可见的静态方法,则可以从
B
调用该方法(无论您是编写
B.staticMethod()
还是
a.staticMethod()
还是
new B().staticMethod()
,都没有关系)


如果以后在
B
中定义了同名的静态方法,该方法会在
a
中隐藏同名的方法,因此调用
B.staticMethod()
new B().staticMethod()
现在调用
B
的静态方法。但是,调用
a.staticMethod()
仍将调用一个的静态方法。

多态性不适用于静态方法。使用JVM指令invokestatic调用静态方法,而使用invokevirtual实现多态性。对静态方法的调用在编译时确定,多态方法在运行时动态调度

只需将新的B()赋值给类型为A的变量,就可以轻松地调整代码,从而调用A.staticMethod()

new B().staticMethod();
不要在同一句话中谈论static和override

整个可重写方法的概念是在运行时动态绑定要执行的方法。

public static void main(String[] args) {
    new B().privateMethod();
    A b = new B(); // change here.
    b.staticMethod(); // A.staticMethod() is called here. 
}
虽然变量
obj
的类型为
A
,但它仍然打印出“B”

另一方面,静态方法在编译时绑定。这意味着编译器使用变量类型(或表达式)来确定要执行的方法:

class A { void print() { out.println("A"); }
class B extends A { void print() { out.println("B"); }

A obj = new B();
obj.print();
这现在会产生“A”。不幸的是,Java语言允许对变量或表达式调用静态方法。不建议这样做!最好对类型本身调用静态方法:

class A { static void print() { out.println("A"); }
class B extends A { static void print() { out.println("B"); }

A obj = new B();
obj.print();
在第一个示例中-
obj.print();
-编译器自动将语句转换为
A.print()
。实际对象不计算在内。事实上,您可以编写以下代码:

A.print();
B.print();
或:


仍然打印“A”。

静态成员不会被覆盖,而是被隐藏。new B().staticMethod();=>这是一种错误的方法。你会让其他人相信它是一种实例方法。调用此方法的正确方法是:B.staticMethod();请您评论一下方法隐藏和重写之间的区别,除了静态方法的调用在编译时由JVM指令invokestatic调用确定,而多态性是在运行时由invokevirtual实现的,以获得更清晰的信息。@dubey theHarcourtians听起来您是在要求我复制内容从另一个答案到我的答案。这听起来不对。我的意思是,除了在编译时根据引用确定的隐藏之外,你可以更清楚地了解它,因为当没有引用意味着它被对象编译器调用时,编译器会假定你在运行时创建的对象的类名,作为静态情况下的引用。
A.print();
B.print();
A obj = null;
obj.print();
((A) null).print();