Equivalent to late static binding(PHP) in other popular languages
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); // Outputs "B"
?>
I want to get an equivalent in Java...so something like
class A {
public static void who(){
System.out.println("A");
};
public static void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
public static void who(){
System.out.println("B");
};
public static void main(String[] args){
B.test(); // Outputs "A" but I want "B"
}
}
I want the who()
call inside A::test
to resolve as in PHP 5.3 by calling B::who
.
EDIT: I know there is no "standard way" of doing this in most popular languages. I'm looking for hacks and such. Also, is this possible in C/C++, or any other popular OOP language?
This is not for any real design on anything. I'm just being curious.
Not possible in Java. (At least not without ugly reflection hacks.)
I encourage you to rethink your design and rely on proper objects.
Related question:
Edit: B.test()
will (or can at least according to spec) be compiled into a call to A.test()
, so there's no way to discover how the call was made from within A.test()
. In other words, there's no way to let the behaviour of A.test
depend on if it was called through A.test()
or B.test()
.
Since you're asking out of curiosity, here's AFAIK the closest "solution".
test
with a test(Class<?> c)
which takes as argument the class which defines the intended who
method. test()
in class B
. A.test
slightly. In code:
class A {
public static void who() {
System.out.println("A");
}
public static void test() {
test(A.class);
}
public static void test(Class<?> c) {
//who(); //<<< How to implement a static:: thing here???
try {
c.getMethod("who").invoke(null); // Call static who on given class.
} catch (Exception e) {
}
}
}
public class B extends A {
public static void who(){
System.out.println("B");
}
public static void test() {
test(B.class);
}
public static void main(String[] args){
A.test(); // Outputs "A"
B.test(); // Outputs "B"
}
}
It seems that the compiler generates a call to B.test
in the bytecode even though B
doesn't declare a method named test
.
Bytecode of main method:
invokestatic #5 = Method B.test(()V)
return
Given the names of a class and method ( "B"
and "who"
) you can easily use reflection to call the method. So the question becomes
Can you extract B
by combining the call stack and bytecode inside A.test
?
You'll need to use the return address stored on the stack to locate the call to B.test
in the bytecode and extract the declared call. There are plenty of bytecode manipulation libraries, but I don't know if any of them allow you to tie that to the execution stack in the JVM.
You can't override static methods in java.
http://geekexplains.blogspot.co.uk/2008/06/can-you-override-static-methods-in-java.html
链接地址: http://www.djcxy.com/p/82426.html