Java 如何处理静态方法重写?

Java 如何处理静态方法重写?,java,oop,Java,Oop,比如说, public class A { public static int f() { return 1; } } public class B extends A { public static long f() { return 100L; } } 不幸的是,B.f()无法编译,因为B.f()试图覆盖A.f(),因此名称冲突,因为返回类型不兼容 我很好奇重写静态方法的目的是什么?有任何用例吗?我能躲在B班吗 实际使用情况: class EntityDTO {

比如说,

public class A {
    public static int f() { return 1; }
}

public class B extends A {
    public static long f() { return 100L; }
}
不幸的是,
B.f()
无法编译,因为
B.f()
试图覆盖
A.f()
,因此名称冲突,因为返回类型不兼容

我很好奇重写静态方法的目的是什么?有任何用例吗?我能躲在B班吗

实际使用情况:

class EntityDTO {

    public static List<EntityDTO> marshal(Collection<? extends Entity> entities) {
        ...
    }

}

class BookDTO extends EntityDTO {

    public static List<BookDTO> marshal(Collection<? extends Book> books) {
        ...
    }

}
class EntityDTO{

无法重写公共静态列表封送处理(集合静态方法)


注意:要通过编译,您的
B.f()
应该返回int而不是long。

静态方法不能被重写


注意:你的
B.f()
应该返回int而不是long才能通过编译。

也许您需要重新考虑您的设计,如果您需要重写封送处理方法,那么它首先不应该是静态的。

也许您需要重新考虑您的设计,如果您需要重写封送处理方法,那么它首先不应该是静态的

严格地说,静态方法是不能被重写的。方法重写是对象多态性独有的特性,静态方法不属于任何对象,而是属于类本身


在阐明了这一点之后,您不应该使任何方法
成为静态的
。这至少可以解决您手头上的问题。由于方法参数不同,它将不会被视为重写,而是重载。

严格地说,静态方法不能被重写。方法重写是object独有的功能多态性和静态方法不属于任何对象,而是属于类本身


在阐明了这一点之后,您不应该将任何方法设置为静态的。这至少可以解决您手头上的问题。由于方法参数不同,它不会被视为重写,而是重载。

静态方法不会被重写……但它被称为方法隐藏。使用相同方法名称的好处是参数就像任何其他方法覆盖的好处一样

静态方法不会被覆盖…但它被称为方法隐藏。使用相同的方法名称和参数的好处就像任何其他方法覆盖的好处一样

我想不出一个覆盖静态函数的用例(在Java中)可能很有用,但如果你绝对必须做到这一点,以下是方法:

import java.lang.reflect.Method;

class A {

    public static void callOut() {

        System.out.println("A.callOut");
    }

}

public class B extends A {

    public static void callOut() {

        System.out.println("B.callOut");
    }

    public static void main(String[] args) throws Exception
    {
        A a = new A();
        A b = new B();

        Method aM = a.getClass().getMethod("callOut");
        Method bM = b.getClass().getMethod("callOut");

        aM.invoke(null); // prints A.callOut
        bM.invoke(null); // prints B.callOut
    }
}

我想不出重写静态函数(在Java中)会有用的用例,但如果您必须实现它,下面是如何实现的:

import java.lang.reflect.Method;

class A {

    public static void callOut() {

        System.out.println("A.callOut");
    }

}

public class B extends A {

    public static void callOut() {

        System.out.println("B.callOut");
    }

    public static void main(String[] args) throws Exception
    {
        A a = new A();
        A b = new B();

        Method aM = a.getClass().getMethod("callOut");
        Method bM = b.getClass().getMethod("callOut");

        aM.invoke(null); // prints A.callOut
        bM.invoke(null); // prints B.callOut
    }
}

有非静态的
封送()
s哪个做真正的封送处理。静态方法是封送集合的辅助函数。IMHO,静态方法总是通过类而不是实例调用,所以为什么还要麻烦重写呢?我完全没有注意到您的编译问题,虽然您说静态方法是通过类访问的,但子类也可以访问父类的静态方法,它们可以由子类隐藏或重载。在您给出的示例中,由于两种情况下的方法签名(参数)相同,因此它既不隐藏也不重载,因此会显示错误消息。存在非静态的
封送()
s哪个做真正的封送处理。静态方法是封送集合的辅助函数。IMHO,静态方法总是通过类而不是实例调用,所以为什么还要麻烦重写呢?我完全没有注意到您的编译问题,虽然您说静态方法是通过类访问的,但子类也可以访问父类的静态方法,它们可以被子类隐藏或重载对于这两种情况都是一样的,它既不隐藏也不重载,因此会显示错误消息。我建议将方法重命名为marshalEntity和marshalBook。或者BookDTO不应该扩展EntityTo?我建议将方法重命名为marshalEntity和marshalBook。或者BookDTO不应该扩展EntityTo?我看不出您的意思。我们为这一点调用反射简直是杀伤力过大。通过执行
A.callOut();B.callOut();
,您可以实现完全相同的效果。事实上,当我解除绑定并调用方法时,我不知道(或关心)它们的类。想象一下,拥有一个包含A&B实例的数组并在其上循环:A[]ary=新的A[100];/*填充数组*/;for(A:ary){a.getClass().getMethod(“callOut”).invoke(null);};会正确调用特定的callOut方法。我看不出你在说什么。使用反射来实现这一点只是矫枉过正。通过执行
a.callOut();B.callOut();
可以实现完全相同的效果。实际上,关键是当我解除绑定并调用这些方法时,我不知道(或在乎)假设有一个包含A&B实例的数组并在其上循环:A[]ary=newa[100];/*fill array up*/;for(A:ary){A.getClass().getMethod(“callOut”).invoke(null);};将正确调用特定的callOut方法。