Can you override Static Methods in Java?
来源:互联网 发布:域名是否备案查询 编辑:程序博客网 时间:2024/04/30 14:22
Many people have heard that you can't override a static method. This is true - you can't. However it is possible to write code like this:
This compiles and runs just fine. Isn't it an example of a static method overriding another static method? The answer is no - it's an example of a static method hiding another static method. If you try to override a static method, the compiler doesn't actually stop you - it just doesn't do what you think it does.
class Foo {
public static void method() {
System.out.println("in Foo");
}
}
class Bar extends Foo {
public static void method() {
System.out.println("in Bar");
}
}
So what's the difference?
Briefly, when you override a method, you still get the benefits of run-time polymorphism, and when you hide, you don't. So what does that mean? Take a look at this code:
If you run this, the output is
class Foo {
public static void classMethod() {
System.out.println("classMethod() in Foo");
}
public void instanceMethod() {
System.out.println("instanceMethod() in Foo");
}
}
class Bar extends Foo {
public static void classMethod() {
System.out.println("classMethod() in Bar");
}
public void instanceMethod() {
System.out.println("instanceMethod() in Bar");
}
}
class Test {
public static void main(String[] args) {
Foo f = new Bar();
f.instanceMethod();
f.classMethod();
}
}
instanceMethod() in BarWhy do we get instanceMethod from Bar, but classMethod() from Foo? Aren't we using the same instance f to access both of these? Yes we are - but since one is overriding and the other is hiding, we see different behavior.
classMethod() in Foo
Since instanceMethod() is (drum roll please...) an instance method, in which Bar overrides the method from Foo, at run time the JVM uses the actual class of the instance f to determine which method to run. Although f was declared as a Foo, the actual instance we created was a new Bar(). So at runtime, the JVM finds that f is a Bar instance, and so it calls instanceMethod() in Bar rather than the one in Foo. That's how Java normally works for instance methods.
With classMethod() though. since (ahem) it's a class method, the compiler and JVM don't expect to need an actual instance to invoke the method. And even if you provide one (which we did: the instance referred to by f) the JVM will never look at it. The compiler will only look at the declared type of the reference, and use that declared type to determine, at compile time, which method to call. Since f is declared as type Foo, the compiler looks at f.classMethod() and decides it means Foo.classMethod. It doesn't matter that the instance reffered to by f is actually a Bar - for static methods, the compiler only uses the declared type of the reference. That's what we mean when we say a static method does not have run-time polymorphism.
Because instance methods and class methods have this important difference in behavior, we use different terms - "overriding" for instance methods and "hiding" for class methods - to distinguish between the two cases. And when we say you can't override a static method, what that means is that even if you write code that looks like it's overriding a static method (like the first Foo and Bar at the top of this page) - it won't behave like an overridden method.
So what about accessing a static method using an instance?
It's possible in Java to write something like:
f.classMethod();
where f is an instance of some class, and classMethod() is a class method (i.e. a static method) of that class. This is legal, but it's a bad idea because it creates confusion. The actual instance f is not really important here. Only the declared type of f matters. That is, what class is f declared to be? Since classMethod() is static, the class of f (as determined by the compiler at compile time) is all we need.
Rather than writing:
f.classMethod();It would be better coding style to write either:
Foo.classMethod();or
Bar.classMethod();That way, it is crystal clear which class method you would like to call. It is also clear that the method you are calling is indeed a class method.o;'oi;'iBarring that, you could always come up with this monstrosity:
f.getClass().getMethod("classMethod", new Class[]).invoke(null, new Object[]);
But all this could be avoided by simply not trying to override your static (class) methods. :-)
Why does the compiler sometimes talk about overriding static methods?
Sometimes you will see error messages from the compiler that talk about overriding static methods. Apparently, whoever writes these particular messages has not read the Java Language Specification and does not know the difference between overriding and hiding. So they use incorrect and misleading terminology. Just ignore it. The Java Language Specification is very clear about the difference between overriding and hiding, even if the compiler messages are not. Just pretend that the compiler said "hide" rather than "override"..
- Can you override Static Methods in Java?
- Can you override Static Methods in Java?
- Something about static Methods in C++ you should know
- The Default Methods And Static Methods In Java Interface
- Interface in Java 8(Default/Static methods)
- Question 16: Which of the following methods can a developer use to override the default terminate() function in C++?
- Can we Override Private Method in Java? Inner Class?
- Override in Java(Note)
- 17.5.4 Override methods
- 17.5.4 Override methods
- Source->Override/Implement Methods
- Can you sleep in storm night?
- Can you sleep in storm night?[2]
- you can only work in client 800
- Override and Overload in Java
- java static i hate you
- Unfortunately you can't have non-Gradle Java modules and Android-Gradle modules in one project.
- Unfortunately you can't have non-Gradle Java modules and Android-Gradle modules in one project.
- 【转载】weka中文乱码解决办法
- 浅谈Python的选择
- java Future 接口介绍
- 还剩3000万用户 小灵通一年后将退网
- 屏幕截图(带光标)
- Can you override Static Methods in Java?
- CentOS 5.5通过yum安装 Memcached的步骤、问题、及解决办法
- 使用axis编写客户端代码调用webservice的一些问题
- C# WinForm 设置DataGridView选中指定行
- 仿QQ广告栏
- 改颜色
- 第6章 语句
- 微软公司2010年度十大新闻
- ADO 连接EXCEL显示在DBGRID中找不到可安装的ISAM