相当于其他流行语言中的晚期静态绑定(PHP)

<?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"
?>

我想在Java中获得一个相当于...的东西

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"
     }
}

我想通过调用B::who来解决A::testwho()调用,就像在PHP 5.3中解析一样。

编辑:我知道在大多数流行语言中没有这样做的“标准方式”。 我正在寻找黑客等。 另外,这是可能的C / C + +,或任何其他流行的OOP语言?

这不适用于任何真正的设计。 我只是好奇。


在Java中不可能。 (至少不是没有丑陋的反射黑客。)

我鼓励你重新考虑你的设计并依靠适当的对象。

相关问题:

  • 我可以重写和重载Java中的静态方法吗?
  • 编辑: B.test()将(或至少可以根据规范)被编译成一个呼叫A.test()所以没有办法发现如何调用从内作出A.test() 换句话说,有没有办法让的行为A.test取决于它是否是通过所谓的A.test()B.test()

    既然你是出于好奇,这里是AFAIK最接近的“解决方案”。

  • 用一个test(Class<?> c)重载test ,该test(Class<?> c)以定义预期的who方法的类作为参数。
  • 在类B隐藏(注意你不能覆盖) test()
  • 稍微改变A.test的实现。
  • 在代码中:

    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"
         }
    }
    

    看起来,即使B没有声明名为test的方法,编译器B.test在字节码中生成对B.test的调用。

    Bytecode of main method:
    
    invokestatic #5 = Method B.test(()V)
    return
    

    给定一个类和方法的名字( "B""who" ),你可以很容易地使用反射来调用该方法。 所以问题就变成了

    您可以提取B通过组合内的调用堆栈和字节A.test

    您需要使用存储在堆栈中的返回地址来定位对字节码中B.test的调用,并提取声明的调用。 有很多字节码操作库,但我不知道它们中的任何一个是否允许将它们绑定到JVM中的执行堆栈。


    你不能重写java中的静态方法。

    http://geekexplains.blogspot.co.uk/2008/06/can-you-override-static-methods-in-java.html

    链接地址: http://www.djcxy.com/p/82425.html

    上一篇: Equivalent to late static binding(PHP) in other popular languages

    下一篇: Backspace in HTML