为什么Java不允许重写静态方法?

为什么不可能覆盖静态方法?

如果可能,请使用示例。

重写取决于有一个类的实例。 多态性的要点是你可以inheritance一个类,实现这些子类的对象对于在超类中定义的相同的方法(在子类中被覆盖)将具有不同的行为。 静态方法不与任何类的任何实例关联,所以这个概念是不适用的。

Java的devise有两个考虑因素影响了这一点。 其中之一就是性能方面的问题:Smalltalk对它的速度太慢了(垃圾回收和多态的调用是其中的一部分),Java的创build者决心避免这种情况。 另一个是Java的目标受众是C ++开发者的决定。 使得静态方法的工作方式对于C ++程序员来说是熟悉的,而且速度也非常快,因为不需要等到运行时才能确定调用哪个方法。

我个人认为这是Javadevise中的一个缺陷。 是的,是的,我知道非静态方法附加到一个实例,而静态方法附加到一个类等等,但仍然考虑下面的代码:

 public class RegularEmployee { private BigDecimal salary; public void setSalary(BigDecimal salary) { this.salary = salary; } public static BigDecimal getBonusMultiplier() { return new BigDecimal(".02"); } public BigDecimal calculateBonus() { return salary.multiply(getBonusMultiplier()); } /* ... presumably lots of other code ... */ } public class SpecialEmployee extends RegularEmployee { public static BigDecimal getBonusMultiplier() { return new BigDecimal(".03"); } } 

这个代码不会像你所期望的那样工作。 也就是说,SpecialEmployee像普通员工一样获得2%的奖金。 但是如果你删除了“静态”,那么SpecialEmployee就会获得3%的奖金。

(不可否认,这个例子是不好的编码风格,因为在现实生活中,你可能希望奖金乘数在某个数据库而不是硬编码的数据库中,但这只是因为我不想让这个例子很多与代码无关的代码。)

我觉得你可能想让getBonusMultiplier是静态的。 也许您希望能够显示所有员工类别的奖金乘数,而不需要在每个类别中都有员工的实例。 search这样的例子有什么意义? 如果我们要创build一个新的员工类别,而又没有任何员工分配给他们呢? 这在逻辑上是一个静态函数。

但它不起作用。

是的,是的,我可以想出许多方法来重写上面的代码,使其工作。 我的观点并不是它造成了一个无法解决的问题,而是它为粗心的程序员创造了一个陷阱,因为这个语言并不像我认为的合理的人所期望的那样行事。

也许如果我试图编写OOP语言的编译器,我很快就会明白为什么要实现它,以便可以重写静态函数将是困难的或不可能的。

或者Java的这种行为也许有一个很好的理由。 任何人都可以指出这种行为的优势,一些types的问题,由此更容易? 我的意思是,不要只是指向我的Java语言规范,并说“看,这是logging它如何performance”。 我知道。 但是,为什么它应该这样呢? (除了明显的“让它工作正确太难”…)

更新

@VicKirk:如果你的意思是这是“糟糕的devise”,因为它不适合Java处理静态的问题,我的回答是,“呃,当然。 正如我在我原来的post所说,这是行不通的。 但是如果你的意思是这样的devise是不好的,那么这种语言在某种程度上可能会出现根本性的错误,也就是说静态可以像虚拟函数一样被覆盖,这样会引起模糊或者不可能有效地实施或者这样做,我回答:“为什么?这个概念有什么问题?”

我想我给的例子是一件很自然的事。 我有一个类有一个函数,不依赖于任何实例数据,我可能非常合理地要独立于一个实例调用,以及想要在实例方法内调用。 为什么这不行? 这些年来,我已经遇到了相当多的情况。 在实践中,我通过使函数变成虚拟来解决这个问题,然后创build一个静态方法,其唯一目的就是将虚拟方法传递给具有虚拟实例的静态方法。 这似乎是一个非常迂回的方式去那里。

简单的答案是:完全可能,但是Java并没有这样做。

下面是一些说明Java中当前状态的代码:

File Base.java

 package sp.trial; public class Base { static void printValue() { System.out.println(" Called static Base method."); } void nonStatPrintValue() { System.out.println(" Called non-static Base method."); } void nonLocalIndirectStatMethod() { System.out.println(" Non-static calls overridden(?) static:"); System.out.print(" "); this.printValue(); } } 

文件Child.java

 package sp.trial; public class Child extends Base { static void printValue() { System.out.println(" Called static Child method."); } void nonStatPrintValue() { System.out.println(" Called non-static Child method."); } void localIndirectStatMethod() { System.out.println(" Non-static calls own static:"); System.out.print(" "); printValue(); } public static void main(String[] args) { System.out.println("Object: static type Base; runtime type Child:"); Base base = new Child(); base.printValue(); base.nonStatPrintValue(); System.out.println("Object: static type Child; runtime type Child:"); Child child = new Child(); child.printValue(); child.nonStatPrintValue(); System.out.println("Class: Child static call:"); Child.printValue(); System.out.println("Class: Base static call:"); Base.printValue(); System.out.println("Object: static/runtime type Child -- call static from non-static method of Child:"); child.localIndirectStatMethod(); System.out.println("Object: static/runtime type Child -- call static from non-static method of Base:"); child.nonLocalIndirectStatMethod(); } } 

如果你运行这个(我使用Java 1.6在Mac平台上,使用Java 1.6),你会得到:

 Object: static type Base; runtime type Child. Called static Base method. Called non-static Child method. Object: static type Child; runtime type Child. Called static Child method. Called non-static Child method. Class: Child static call. Called static Child method. Class: Base static call. Called static Base method. Object: static/runtime type Child -- call static from non-static method of Child. Non-static calls own static. Called static Child method. Object: static/runtime type Child -- call static from non-static method of Base. Non-static calls overridden(?) static. Called static Base method. 

在这里, 唯一可能出乎意料的问题(问题的关键)似乎是第一个案例:

“运行时types不用于确定调用哪个静态方法,即使使用对象实例( obj.staticMethod() )调用。

最后的情况:

“当从一个类的对象方法中调用一个静态方法时,所select的静态方法是可以从类本身访问的,而不是从定义该对象的运行时types的类访问的。

调用一个对象实例

静态调用在编译时parsing,而非静态方法调用在运行时parsing。 请注意,尽pipe静态方法是从父类inheritance的 ,但它们不会被子类覆盖 。 如果你期望的话,这可能是一个惊喜。

从对象方法中调用

对象方法调用使用运行时types来parsing,但静态( )方法调用使用编译时(声明)types来parsing。

改变规则

为了改变这些规则,以便在示例中的最后一个调用Child.printValue() ,静态调用必须在运行时提供一个types,而不是编译器在声明的类中parsing调用的对象(或上下文)。 然后,静态调用可以使用(dynamic)types层次来parsing调用,就像对象方法调用所做的那样。

这很容易实现(如果我们改变了Java:-O)并不是不合理的,但是它有一些有趣的考虑。

主要的考虑是我们需要决定哪个静态方法调用应该这样做。

目前,Java在obj.staticMethod()调用被ObjectClass.staticMethod()调用(通常带有警告)取代的语言中有这个“怪癖”。 [ 注意: ObjectClassobj的编译时间types]这些将是以这种方式重写的好select,采用运行时types的obj

如果我们这样做,会使方法体难以阅读:父类中的静态调用可能被dynamic地 “重新路由”。 为了避免这种情况,我们必须用一个类名来调用静态方法 – 这使得调用更加明显的解决了编译时types层次结构(就像现在一样)。

调用静态方法的其他方法更为棘手: this.staticMethod()应该与obj.staticMethod()相同,并且使用这个types的运行时types。 然而,这可能会导致一些现有的程序头痛,这些程序调用(显然是本地的)静态方法而没有装饰(这可以等价于this.method() )。

那么,如何调用staticMethod()呢? 我build议他们和今天一样做,用当地的上下文来决定做什么。 否则会产生很大的混乱。 当然,如果method是一个非静态方法,那么method()就意味着this.method() ,而ThisClass.method() if method是一个静态方法。 这是混乱的另一个来源。

其他的考虑

如果我们改变了这个行为(并且使得静态调用可能是dynamic的非本地的),我们可能会想要重新审视finalprivateprotected的含义作为类的static方法的限定符。 那么我们就必须习惯于这样一个事实,即private staticpublic final方法不会被覆盖,因此可以在编译时被安全地解决,并且作为本地引用来读取是“安全的”。

其实我们错了
尽pipeJava不允许在默认情况下覆盖静态方法,但是如果仔细查看Java中的Class和Method类的文档,仍然可以find一种方法来仿效以下解决方法覆盖静态方法:

 import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; class RegularEmployee { private BigDecimal salary = BigDecimal.ONE; public void setSalary(BigDecimal salary) { this.salary = salary; } public static BigDecimal getBonusMultiplier() { return new BigDecimal(".02"); } public BigDecimal calculateBonus() { return salary.multiply(this.getBonusMultiplier()); } public BigDecimal calculateOverridenBonus() { try { // System.out.println(this.getClass().getDeclaredMethod( // "getBonusMultiplier").toString()); try { return salary.multiply((BigDecimal) this.getClass() .getDeclaredMethod("getBonusMultiplier").invoke(this)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } return null; } // ... presumably lots of other code ... } final class SpecialEmployee extends RegularEmployee { public static BigDecimal getBonusMultiplier() { return new BigDecimal(".03"); } } public class StaticTestCoolMain { static public void main(String[] args) { RegularEmployee Alan = new RegularEmployee(); System.out.println(Alan.calculateBonus()); System.out.println(Alan.calculateOverridenBonus()); SpecialEmployee Bob = new SpecialEmployee(); System.out.println(Bob.calculateBonus()); System.out.println(Bob.calculateOverridenBonus()); } } 

结果输出:

 0.02 0.02 0.02 0.03 

我们正在努力实现:)

即使我们将第三个variablesCarl声明为RegularEmployee并将其分配给SpecialEmployee的实例,我们仍然会在第一种情况下调用RegularEmployee方法,在第二种情况下调用SpecialEmployee方法

 RegularEmployee Carl = new SpecialEmployee(); System.out.println(Carl.calculateBonus()); System.out.println(Carl.calculateOverridenBonus()); 

只要看看输出控制台:

 0.02 0.03 

;)

静态方法被JVM视为全局对象,根本没有绑定到对象实例。

从概念上说,如果你可以从类对象中调用静态方法(比如像Smalltalk这样的语言),但在Java中不是这样。

编辑

你可以重载静态方法,没关系。 但是你不能重写一个静态方法,因为class不是一stream的对象。 您可以在运行时使用reflection来获取对象的类,但是获取的对象不会与类层次结构并行。

 class MyClass { ... } class MySubClass extends MyClass { ... } MyClass obj1 = new MyClass(); MySubClass obj2 = new MySubClass(); ob2 instanceof MyClass --> true Class clazz1 = obj1.getClass(); Class clazz2 = obj2.getClass(); clazz2 instanceof clazz1 --> false 

你可以反思课程,但是在那里停下来。 您不通过使用clazz1.staticMethod() ,而是使用MyClass.staticMethod()来调用静态方法。 一个静态方法不会被绑定到一个对象上,因此在静态方法中不存在thissuper概念。 静态方法是一个全局函数; 结果也没有多态性的概念,因此,方法重写是没有意义的。

但是,如果MyClass是运行时的一个对象,就像在Smalltalk中一样(或者JRuby作为一个注释提示,但是我对JRuby一无所知),那么这可能是可能的。

噢,还有一件事。 你可以通过一个对象obj1.staticMethod()来调用一个静态方法,但是MyClass.staticMethod()是真正的语法糖,应该避免。 它通常会在现代IDE中提出警告。 我不知道为什么他们允许这个捷径。

方法重写可以通过dynamic分派来实现 ,这意味着对象的声明types不确定其行为,而是确定其运行时types:

 Animal lassie = new Dog(); lassie.speak(); // outputs "woof!" Animal kermit = new Frog(); kermit.speak(); // outputs "ribbit!" 

尽pipelassiekermit都声明为Animaltypes的对象,但它们的行为(method .speak() )会有所不同,因为dynamic分派只会在运行时将方法调用.speak() 绑定到实现 – 而不是在编译时。

现在,这里是static关键字开始有意义的地方: “静态”一词是“dynamic”的反义词。 所以你不能重写静态方法的原因是因为在静态成员上没有dynamic调度 – 因为静态字面意思是“不dynamic”。 如果他们dynamic调度(因此可能被覆盖) static关键字只是没有意义了。

在Java中(和许多OOP语言,但我不能说全部;有些没有静态)所有的方法有一个固定的签名 – 参数和types。 在虚拟方法中,第一个参数是隐含的:对象本身的引用,当从对象内部调用时,编译器会自动添加this

静态方法没有区别 – 它们仍然有一个固定的签名。 但是,通过声明静态方法,您明确指出编译器在该签名的开头不得包含隐含的对象参数。 因此,任何其他调用这个函数的代码都不能试图把一个对象引用到堆栈上 。 如果这样做了,那么方法执行将不起作用,因为参数将在堆栈上错误的位置上移动。

由于这两者之间的差异, 虚拟方法总是具有对上下文对象的引用(即this ),因此可以引用堆中属于该对象实例的任何内容。 但是对于静态方法,由于没有引用传递,因为上下文不知道,所以该方法不能访问任何对象variables和方法。

如果你希望Java能够改变定义,那么为每个方法(静态或虚拟)传递一个对象上下文,那么你实际上只有虚拟方法。

正如有人问你对这个function的评论 – 你想要这个function的原因和目的是什么?

我不太了解Ruby,就像OP提到的那样,我做了一些研究。 我发现在Ruby中,类实际上是一种特殊的对象,可以创build(甚至dynamic地)新的方法。 类是Ruby中的完整类对象,它们不在Java中。 这只是在使用Java(或C#)时必须接受的。 这些不是dynamic语言,但C#正在添加一些dynamicforms。 实际上,我没有find“静态”方法,在这种情况下,这些是单例类对象上的方法。 然后你可以用一个新类来覆盖这个单例,前一个类对象中的方法将调用新类中定义的方法(正确?)。 因此,如果您在原始类的上下文中调用了一个方法,它仍然只会执行原始的静态方法,但是在派生类中调用一个方法将会从父类或子类中调用方法。 有趣的,我可以看到一些价值。 它采取不同的思维模式。

既然你正在使用Java,你将需要适应这种做事的方式。 他们为什么这样做? 那么,可能是基于现有的技术和理解来提高性能。 计算机语言不断发展。 回到足够远,没有OOP这样的事情。 未来还会有其他新的想法。

编辑 :另一个评论。 现在我看到了差异,就像我自己的Java / C#开发人员一样,我可以理解为什么从Java开发人员那里得到的答案可能会让您感到困惑,如果您是来自Ruby这样的语言。 Java static方法与Ruby class方法不一样。 Java开发人员很难理解这一点,相反,那些主要使用诸如Ruby / Smalltalk之类的语言的开发人员也是如此。 我可以看到,Java也使用“类方法”作为讨论静态方法的另一种方式,但是Ruby的使用方式与此不同,这一点也会让人大惑不解。 Java没有Ruby风格的类方法(对不起); Ruby没有Java风格的静态方法,这些方法实际上只是一些旧的过程风格函数,如C中所见。

顺便说一句 – 谢谢你的问题! 我今天为我学到了一些关于类方法(Ruby风格)的新东西。

一般来说,允许“重写”静态方法是没有意义的,因为没有好的方法来确定在运行时调用哪一个。 以Employee例子来说,如果我们调用RegularEmployee.getBonusMultiplier() – 哪个方法应该被执行?

在Java的情况下,人们可以想象一个语言定义,只要通过对象实例调用静态方法,就可以“覆盖”静态方法。 然而,所有这些都是为了重新实现常规的类方法,增加了语言的冗余,而没有真正增加任何好处。

重写被保留给实例成员以支持多态行为。 静态类成员不属于特定的实例。 相反,静态成员属于类,因此不支持覆盖,因为子类只inheritance保护和公共实例成员,而不是静态成员。 您可能需要定义一个界面和研究工厂和/或策略devise模式来评估一种替代方法。

那么…答案是否定的,如果你从一个重写的方法应该如何performance在Java的angular度来思考。 但是,如果您尝试覆盖静态方法,则不会收到任何编译器错误。 这意味着,如果您尝试重写,Java不会阻止您这么做; 但你肯定不会得到与非静态方法相同的效果。 在Java中重写只是意味着特定的方法将基于对象的运行时types而不是它的编译时types(这是被覆盖的静态方法的情况)被调用。 好吧…为什么他们的行为奇怪呢? 因为它们是类方法,因此只有在编译时才使用编译时types信息来parsing对它们的访问。 使用对象引用访问它们只是Javadevise者给出的一个额外的自由,我们当然不应该想到只有当它限制它时才停止这种做法:-)

示例 :让我们试着看看如果我们重写一个静态方法会发生什么:

 class SuperClass { // ...... public static void staticMethod() { System.out.println("SuperClass: inside staticMethod"); } // ...... } public class SubClass extends SuperClass { // ...... // overriding the static method public static void staticMethod() { System.out.println("SubClass: inside staticMethod"); } // ...... public static void main(String[] args) { // ...... SuperClass superClassWithSuperCons = new SuperClass(); SuperClass superClassWithSubCons = new SubClass(); SubClass subClassWithSubCons = new SubClass(); superClassWithSuperCons.staticMethod(); superClassWithSubCons.staticMethod(); subClassWithSubCons.staticMethod(); // ... } } 

输出 : –
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod

注意输出的第二行。 如果staticMethod被覆盖,这行应该与第三行相同,因为我们在运行时types的对象上调用“staticMethod()”作为“SubClass”而不是“SuperClass”。 这确认了静态方法总是只使用它们的编译时间types信息来parsing。

我喜欢和加倍周杰伦的评论( https://stackoverflow.com/a/2223803/1517187 )。
我同意这是Java的糟糕的devise。
正如我们在前面的评论中看到的,许多其他语言支持覆盖静态方法。 我觉得Jay也像我一样来自Delphi的Java。
Delphi(Object Pascal)是实现OOP的第一语言。
很显然,很多人都有这种语言的经验,因为它是过去唯一编写商业GUI产品的语言。 而且 – 是的,我们可以在Delphi中覆盖静态方法。 实际上,Delphi中的静态方法被称为“类方法”,而Delphi则有不同的“Delphi静态方法”的概念,它们是早期绑定的方法。 要覆盖你必须使用后期绑定的方法,请声明“虚拟”指令。 所以这是非常方便和直观的,我期望在Java中。

通过重写,我们可以根据对象types创build一个多态性质。 静态方法与对象无关。 所以java不能支持静态方法重写。

在Java中重写只是意味着特定的方法将基于对象的运行时types而不是它的编译时types(这是被覆盖的静态方法的情况)被调用。 由于静态方法是类方法,所以它们不是实例方法,所以它们与引用指向哪个对象或实例无关。事实上,根据静态方法的属性,它属于特定的类,但是可以将其重新声明为子类,但是这个子类并不知道父类的静态方法,因为正如我所说的那样,它只针对那个已经声明的类。使用对象引用访问它们只是Javadevise者给出的一个额外的自由and we should certainly not think of stopping that practice only when they restrict it more details and example http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html

Answer of this question is simple, the method or variable marked as static belongs to the class only, So that static method cannot be inherited in the sub class because they belong to the super class only.

What good will it do to override static methods. You cannot call static methods through an instance.

 MyClass.static1() MySubClass.static1() // If you overrode, you have to call it through MySubClass anyway. 

EDIT : It appears that through an unfortunate oversight in language design, you can call static methods through an instance. Generally nobody does that. 我的错。

By overriding, you achieve dynamic polymorhpism. When you say overridng static methods, the words you are trying to use are contradictory.

Static says – compile time, overriding is used for dynamic polymorphism. Both are opposite in nature, and hence can't be used together.

Dynamic polymorhpic behavior comes when programmer uses an object and accessing an instance method. JRE will map different instance methods of different classes based on what kind of object you are using.

When you say overriding static methods, static methods we will access by using class name, which will be linked at compile time, so there is no concept of linking methods at run time with static methods. So the term "overriding" static methods itself doesn't make any meaning.

Note: even if you access a class method with an object, still java compiler is intelligent enough to find it out, and will do static linking.

Easy solution: Use singleton instance. It will allow overrides and inheritance.

In my system, I have SingletonsRegistry class, which returns instance for passed Class. If instance is not found, it is created.

Haxe language class:

 package rflib.common.utils; import haxe.ds.ObjectMap; class SingletonsRegistry { public static var instances:Map<Class<Dynamic>, Dynamic>; static function __init__() { StaticsInitializer.addCallback(SingletonsRegistry, function() { instances = null; }); } public static function getInstance(cls:Class<Dynamic>, ?args:Array<Dynamic>) { if (instances == null) { instances = untyped new ObjectMap<Dynamic, Dynamic>(); } if (!instances.exists(cls)) { if (args == null) args = []; instances.set(cls, Type.createInstance(cls, args)); } return instances.get(cls); } public static function validate(inst:Dynamic, cls:Class<Dynamic>) { if (instances == null) return; var inst2 = instances[cls]; if (inst2 != null && inst != inst2) throw "Can\'t create multiple instances of " + Type.getClassName(cls) + " - it's singleton!"; } } 

Here is a simple explanation.A static method is associated with a class while an instance method is associated with a particular object.Overrides allow to call different implementation of the overridden methods associated with the particular object. So it is counter-intuitive to override static method which is not even associated with objects but class itself in the first place.So static methods cannot be overridden based on what object is calling it, it will always be associated with the class where it was created.

A Static method, variable, block or nested class belongs to the entire class rather than an object.

A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (ie, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming ie, high cohesion . (remember a constructor is a special kind of method in Java.)

High Cohesion – One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.

Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.


The below piece code tries to override the static method, but will not encounter any compilation error.

 public class Vehicle { static int VIN; public static int getVehileNumber() { return VIN; }} class Car extends Vehicle { static int carNumber; public static int getVehileNumber() { return carNumber; }} 

This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).

Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.

Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.

 public static final int getVehileNumber() { return VIN; } 

Overall, this is upto software designers for where to use the static methods. I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.

Yes..Practically Java's Allows to override static method…And No Theoretically……If you Override a static method in Java then it will compile and run smoothly..but it will lose Polymorphism….which is basic property of Java ..You will Read Everywhere that its not possible try yourself compling and running..you will get your answer…eg.If you Have Class Animal and a static method eat() and you Override that static method in its Subclass lets called it Dog..then when wherever you Assign a Dog object to an Animal Reference and call eat()..according to Java Dog's eat() should have been called..but in static Overriding Animals's eat() will Called..

 class Animal { public static void eat() { System.out.println("Animal Eating"); } } class Dog extends Animal{ public static void eat() { System.out.println("Dog Eating"); } } class Test { public static void main(String args[]) { Animal obj= new Dog();//Dog object in animal obj.eat(); //should call dog's eat but it didn't } } Output Animal Eating 

According to Polymorphism Principle of Java the Output Should be Dog Eating .
But the result was different because to support Polymorphism Java uses Late Binding that means methods are called only at the run-time but not in the case of static methods..In static methods compiler calls methods at the compile time rather than the run-time..so we get methods according to the reference and not according to the object a reference a containing..that's why You can say Practically it supports static overring but theoretically it doesn't…

Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass .

We can access static methods of super class with subclass reference if this static method has not been hidden by new static method defined in sub class.

For Example, see below code:-

 public class StaticMethodsHiding { public static void main(String[] args) { SubClass.hello(); } } class SuperClass { static void hello(){ System.out.println("SuperClass saying Hello"); } } class SubClass extends SuperClass { // static void hello() { // System.out.println("SubClass Hello"); // } } 

Output:-

 SuperClass saying Hello 

See Java oracle docs and search for What You Can Do in a Subclass for details about hiding of static methods in sub class.

谢谢

The following code shows that it is possible:

 class OverridenStaticMeth { static void printValue() { System.out.println("Overriden Meth"); } } public class OverrideStaticMeth extends OverridenStaticMeth { static void printValue() { System.out.println("Overriding Meth"); } public static void main(String[] args) { OverridenStaticMeth osm = new OverrideStaticMeth(); osm.printValue(); System.out.println("now, from main"); printValue(); } }