Rust 与 Java 静态方法以及对泛型类型参数的调用

  • rust中,我们可以做这样的事情:

    trait MyTrait {
        fn my_func();
    }
    
    struct MyStruct {}
    
    impl MyTrait for MyStruct {
        fn my_func() {
            // this gets invoked
        }
    }
    
    fn my_func<B: MyTrait>() {
        // This here
        B::my_func();
    }
    
    fn main() {
        my_func::<MyStruct>();
    }
    
  • java中,我们不能做这样的事情:

    interface MyInterface {
        public static void myFunc() {
            // This gets invoked
        }
    }
    
    class MyClass implements MyInterface {
        public static void myFunc() {
    
        }
    }
    
    public class Main {
    
        static <T extends MyInterface> void myFunc() {
            // This here
            T.myFunc();
        }
    
        public static void main(String[] args) {
            Main.<MyClass>myFunc();
        }
    }
    

现在还有其他问题关于为什么 java 不允许在 java 中覆盖/强制执行静态方法,但是这个 特定示例 是否因为 单态化与类型擦除而不起作用 >?我试图了解更深层次的原因。 我的猜测是因为类型擦除后只有一个实现,并且需要编译静态调用,所以它不起作用。这是真正的原因吗

xiaoylcs721521 回答:Rust 与 Java 静态方法以及对泛型类型参数的调用

正如您所指出的,类型擦除发生并且 Java 泛型可以被视为语法糖。它用于类型检查,但在 resulting byte code,it will be replaced 中。

如果是未绑定类型,则替换为Object,但在您的示例中,它是绑定类型(T extends MyInterface),因此将替换为MyInterface反而。这就是调用 MyInterface.myFunc 的原因。

为什么编译器不像在 Rust 或 C++ 中那样解析它?我认为这是可能的,所以我只能推测 Java 中的设计决策。 Java 本质上比 Rust 更具动态性。新类可以在注释处理期间定义,但也可以动态创建。该属性在编译时分辨率方面表现不佳,因为编译器在编译时无法了解所有类。

Java 主要是一种面向对象的语言,而 Rust 和 C++ 更强调编译阶段。尽管 Java 是静态类型的,但它更具动态性,并且更多是在运行时完成的。这使它更灵活,但牺牲了性能。

表达您提供的 Rust 代码的“Java 方式”是使用普通函数而不是 static 函数。效果是相似的,但你最终会得到动态调度。 Rust like C++ 遵循零开销原则,因此被迫使用动态调度会违反该原则。另一方面,在 Java 中,它不是设计目标。

通常,JIT 仍然应该能够对其进行优化(即消除动态调度并内联代码)。但是没有像在等效的 Rust(或 C++)中那样保证,在编译时决定一切。

,

我想明确说明 static 在 java 中不是继承的。 因此,该方法需要一个实例化,无论是单例。

interface MyInterface {
    public void myFunc() {
        // This gets invoked
    }
}

class MyClass implements MyInterface {
    @Override // Does not work with static.
    public void myFunc() {

    }
}

public class Main {

    static void myFunc(MyInterface obj) {
        // This here
        obj.myFunc();
    }

    public static void main(String[] args) {
        Main.myFunc(new MyClass());
    }
}

您可以隐藏实例 obj,使其成为 static 或其他。

可能 lambdas 是更好的解决方案:

        Main.myFunc(MyClass::myStaticFunc);
本文链接:https://www.f2er.com/750.html

大家都在问