简体   繁体   English

如何防止类型删除?

[英]How to prevent type erasure?

I have a method that i want to refactor, and it looks (well, very much simplified) like this: 我有一个我想重构的方法,它看起来像这样(非常简化):

import com.sun.tools.javac.util.Pair;

private int foo(Pair<String, ?>... params) {
    if (params[0].snd instanceof String) {
        // do something
        return 0;
    } else if (params[0].snd instanceof ArrayList) {
        // do something else
        return 1;
    }
    return -1; // realistically in the code base, this line will never happen **edit: disregard this line
}

so i was thinking i'd do something like split it up into two methods so that i don't have to do type checking. 所以我想我会做一些事情,例如将其分为两种方法,这样我就不必进行类型检查了。 (is this even a good refactor?) (这是否是一个很好的重构?)

so i wanted to do something like this: 所以我想做这样的事情:

private int foo(Pair<String, String>... params) {
    // do something
    return 0;
}

private int foo(Pair<String, ArrayList>... params) {
    // do something else
    return 1;
}

But the compiler keeps telling me that both foo() methods have the same type erasure. 但是编译器一直告诉我,两个foo()方法都具有相同的类型擦除。 Is java just erasing everything that Pair<A, B> knows? Java是否只是擦除Pair<A, B>知道的一切? If so, what's the best way to refactor then? 如果是这样,那么重构的最佳方法是什么? (or does it need refactoring) (或是否需要重构)

At compile time Java will erase the type information of Generics. 在编译时,Java将擦除泛型的类型信息。 There is no way to prevent that. 没有办法防止这种情况。 At runtime, Pair doesn't have <A,B> it is effectively <Object,Object> . 在运行时,Pair没有<A,B>实际上是<Object,Object>

As for refactoring it, there are a few things you might prefer (but apart from one recommendation) there's not much that could be improved in your example - I'd probably use a single else (if that last line can't happen. And I'd use a List instead of a specific type of List. 至于重构,您可能会喜欢一些事情(除了一个建议),您的示例中没有太多可以改进的地方-我可能只用一个(如果最后一行不能发生。)我会使用列表而不是特定类型的列表。

private int foo(Pair<String, ?>... params) {
  if (params[0].snd instanceof String) {
    return 0;
  } else { //if(params[0].snd instanceof List) { //is a List interface, not which List
    // do something else
    return 1;
  }
// return -1; // If it can't happen, why have it here.
}

I would add that 我会补充一点

private int foo(Pair<String, String>... params) {
    return 0;
}

private int foo(Pair<String, ArrayList>... params) {
    return 1;
}

if this code were allowed, it wouldn't have much use. 如果允许使用此代码,则不会有太大用处。 You know what type you're passing into foo. 您知道要传递给foo的类型。 It's whatever the type of the reference is, not the type of the actual object. 不管引用的类型是什么,而不是实际对象的类型。 So just replace all calls to this where you'd pass a Pair<String, String> with just 0 . 因此,只需将所有传递给Pair<String, String> 0替换为对此的所有调用。

That is, which method is called should be determinable at compile time. 也就是说,应在编译时确定调用哪个方法。 Not at runtime. 不在运行时。 And if it's determinable at compile time, you don't need to call the method at all. 而且,如果它在编译时是可确定的,则根本不需要调用该方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM