【问题标题】:how to make the parameters of a method generic如何使方法的参数泛型
【发布时间】:2021-09-07 17:06:39
【问题描述】:

我应该在我的类中创建一个可以接受两种不同类型的对象作为参数的方法,然后在该方法中检查我收到的参数并执行以下操作。例如:

public void check(Object obj){
   if(obj istanceOf MyClassOne)
      ...
   else if(obj istanceOf MyClassTwo)
      ...

我应该如何处理?

【问题讨论】:

  • 那么问题到底是什么?
  • 另外,也许是重载方法而不是泛型?

标签: java object methods


【解决方案1】:

解决方案不明显。

考虑以下示例:

interface I {
    default void print(String method) {
        System.out.println(method + " => " + this.getClass().getCanonicalName());
    }
}

static class A implements I {}
static class A2 extends A {}
static class B implements I {}

static void print(A a) {
    a.print("print(A)");
}

static void print(A2 a2) {
    a2.print("print(A2)");
}

static void print(I i) {
    i.print("print(I)");
}

public static void main(String[] args) {
    print(new A());
    print(new A2());
    print(new B());
}

有输出

print(A) => Test.A
print(A2) => Test.A2
print(I) => Test.B

polymorphic 方法 print 明确承认 AA2I 类型。

注入print 的每种类型都将使用print 多态性的不太通用的形式。这就是为什么print(new A2()); 使用A2 形式,尽管任何形式都适用于这种类型。

但是,它在编译时是正确的,在运行时这是不正确的。

考虑以下示例:

A a2_really = (A) new A2();
print(a2_really);

注入的对象是A2,但是会使用什么方法呢?

print(A) => Test.A2

由于是在编译时解析的,所以在运行时会使用A形式。

结论:

  • 如果您想在编译时强制使用一种或其他方法,您可以编写多态方法。
  • 如果您想检查实例化方法(在运行时创建的对象),请使用反射或使用其他结构(如接口)对您的逻辑进行编码。

【讨论】:

    【解决方案2】:

    如果类不是彼此的超类/子类,您可以使用方法重载:

    public void check(MyClassOne obj) {
        ....
    }
    public void check(MyClassTwo obj) {
        ....
    }
    

    当你调用check(someMyClassOne)时,它将编译使用第一种方法,而对于check(someMyClassTwo),它将编译使用第二种方法。请注意,当您在调用 check 方法的地方知道类型时,这最方便,否则您确实需要使所有要检查的对象扩展一个公共接口或检查它们的实例就像你已经在做的那样。

    【讨论】:

    • 如果一个类扩展另一个类,您的代码可能会在编译时或运行时产生不同的行为。 (见我的回答)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多