【问题标题】:Java simple genericsJava 简单泛型
【发布时间】:2014-05-09 12:34:37
【问题描述】:

如何使用 C++ tempates 之类的方法将这两个函数替换为一个?

public void verify(final int[] array, final int v) {
    for ( final int e : array ) if ( e == v || v == e  ) return;
    abort_operation();
}

public void verify(final double[] array, final double v) {
    for ( final double e : array ) if ( e == v || v ==  e  ) return;
    abort_operation();
}

【问题讨论】:

标签: java templates


【解决方案1】:

你不能,基本上。 Java 泛型不适用于原始类型。您可以通过反射来做到这一点,但这会很丑陋。你也可以使用 boxed 类型,像这样:

public <T> void verify(T[] array, T value) {
   if (!Arrays.asList(array).contains(value)) {
       abortOperation();
   }
}

...但这仅适用于Integer[]Double[],不适用于int[]double[]

这就是为什么Arrays 类对binarySearch 之类的方法有如此多的重载...如果您的方法可以是通用的,那么这些方法也可以。

从根本上说,泛型与 C++ 模板相同。它们涵盖了许多相同的用例,但它们并不相同,您应该不会惊讶地看到其中一个涵盖了某些领域而另一个没有涵盖。

【讨论】:

  • 如果你使用Array反射类就可以了。
  • @PeterLawrey:是的,因此“你可以通过反射来做到这一点”:)
【解决方案2】:

如果你使用 Array 类,你可以

public void verify(final Object array, final double v) {
    for(int i = 0, len = Array.getLength(i); i < len; i++)
        if(((Number) Array.get(array, i)).doubleValue() == v)
             return;
    abort_operation();
}

public void verify(final Object array, final Number v) {
    for(int i = 0, len = Array.getLength(i); i < len; i++)
        if(((Number) Array.get(array, i)).equals(v))
             return;
    abort_operation();
}

注意:所有可能的int 都可以表示为double,因此您可以将v 设为双精度而不损失精度。

这适用于所有数字基元和数字类型。 (注意:某些long 值不能转换为double 而不会损失精度)

如果e == vv == e 也必须为真。

【讨论】:

  • 为什么不直接使用Number 而不是double 而使用equals 呢? (这可能会对 NaN 等产生奇怪的影响,但这比long 不太可能成为问题。)
  • @JonSkeet 正如你所提到的,它很难看。问题是,如果你这样做 verify(new double[] { 1, 2, 3 }, 1) 它会失败。
  • 是的,您需要确保传入正确的 Number 类型。不过,如果您使用原语而不是变量,这更可能是一个问题,我认为我更喜欢它作为“长值可能工作也可能不工作”的警告。
【解决方案3】:

您不能 - 可变类型是原始类型,而泛型不涵盖原始类型。在 Java 10-11 中使用 ...

请注意,您可以使用盒装类型,如果您使用 equals 而不是 ==,它会起作用,并接受可怕的性能和内存占用惩罚...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多