如何在类中为2种通用类型重载函数

huangapple go评论75阅读模式
英文:

How to Overload a function for 2 generic types in a class

问题

我创建了一个具有两个泛型类型(T和K)的类。

public class Categorized3DArrayList<T, K>

然后,我决定为这两个泛型类型创建一个重载的函数。

private T[] assignValue(T[] value, int i, int counter, int size)
{
    T[] target = (T[]) new Object[size];
    if (counter > size)
        return null;
    for (int j = i; j < counter; j++)
    {
        if (value[i] == null)
            return null;
        target[j] = value[j];
    }
    return target;
}

private K[] assignValue(K[] value, int i, int counter, int size)
{
    K[] target = (K[]) new Object[size];
    if (counter > size)
        return null;
    for (int j = i; j < counter; j++)
    {
        if (value[i] == null)
            return null;
        target[j] = value[j];
    }
    return target;
}

因此,出现了以下错误。

方法 assignValue(K[], int, int, int) 的擦除与类型 Categorized3DArrayList<T, K> 中的另一个方法相同

因此,我移除了K[]的重载函数,然后可以这样做。

T[] tempArr = assignValue(array[first][second], 0, currentLength, currentLength);

但是,我无法这样做。

K[] temp_key2 = assignValue(key2[first], 0, key2Length, key2Length);

会出现以下错误消息。

类型 Categorized3DArrayList<T, K> 中的方法 assignValue(T[], int, int, int) 不适用于参数 (K[], int, int, int)

我可以知道在这种情况下发生了什么吗?

在这种情况下,发生了方法重载与Java泛型类型擦除之间的冲突。在Java中,泛型类型在编译时会被擦除,这意味着在运行时,无法区分TK。因此,两个assignValue方法的签名在编译时实际上变得相同,即assignValue(Object[], int, int, int)

当你调用assignValue(key2[first], 0, key2Length, key2Length)时,编译器会尝试匹配最接近的方法,但它会发现只有assignValue(Object[], int, int, int)可用,因此会产生错误。

为了解决这个问题,你可以使用不同的方法名或者使用不同的参数类型来区分这两个方法,以避免冲突。例如,你可以将一个方法命名为assignValueT,另一个方法命名为assignValueK,以明确表示它们分别用于TK类型的数组。

英文:

I created a class with 2 generic types (T and K).

public class Categorized3DArrayList&lt;T,K&gt;

And I decide to create an overloaded function for these 2 generic types

private T[] assignValue(T[] value,int i, int counter, int size)
{   
    T[] target = (T[]) new Object[size];
    if(counter &gt; size)
        return null;
    for(int j = i ;j &lt; counter; j++)
    {
        if(value[i] == null)
         return null;
        target[j] = value[j];
    }
    return target;
}    

private K[] assignValue(K[] value,int i, int counter, int size)
{   
    K[] target = (K[]) new Object[size];
    if(counter &gt; size)
        return null;
    for(int j = i ;j &lt; counter; j++)
    {
        if(value[i] == null)
         return null;
        target[j] = value[j];
    }
    return target;
} 

Hence, this error pops out.

Erasure of method assignValue(K[], int, int, int) is the same as another method in type Categorized3DArrayList&lt;T,K&gt;

So, I take away the overloaded function of K[],
then I am able to do like this

T[] tempArr = assignValue(array[first][second], 0, currentLength, currentLength);

But I cannot do like this

K[] temp_key2 = assignValue(key2[first], 0, key2Length, key2Length);&#39;

This message pops out

The method assignValue(T[], int, int, int) in the type Categorized3DArrayList&lt;T,K&gt; is not applicable for the arguments (K[], int, int, int)

Can I know what is happening in this situation?

答案1

得分: 1

以下是您要翻译的内容:

"It is impossible to have overloaded functions which use generic types for their arguments because of the type erasure."

因为类型擦除,不可能使用泛型类型作为它们的参数来重载函数。

"It should work if additional type information is provided as shown here."

如果提供了额外的类型信息,它应该可以工作如此处所示

"However, the example below shows how the same function may be used for different generic types without explicit type information. It is also recommended to use @SuppressWarnings(&quot;unchecked&quot;) for assignValue."

然而,下面的示例显示了如何在没有显式类型信息的情况下使用相同的函数处理不同的泛型类型。建议还使用 @SuppressWarnings(&quot;unchecked&quot;) 来处理 assignValue

Online demo

在线演示

import java.util.*;

public class Main&lt;K, V&gt;
{
    public &lt;K, V&gt; void foo(K[] arrK, V[] arrV) {
        System.out.println(Arrays.toString(arrK));
        System.out.println(Arrays.toString(arrV));
        K[] resK = assignValue(arrK, 0, arrK.length/2, arrK.length/2);
        V[] resV = assignValue(arrV, 0, arrV.length/2, arrV.length/2);
        System.out.println(Arrays.toString(resK));
        System.out.println(Arrays.toString(resV));
    }
    
    @SuppressWarnings(&quot;unchecked&quot;)
    public &lt;T&gt; T[] assignValue(T[] value, int i, int counter, int size) {
        if(counter &gt; size) {
            return null;
        }
        T[] target = (T[]) new Object[size];
    
        for(int j = i; j &lt; counter; j++) {
            if(value[i] == null) {
                return null;
            }
            target[j] = value[j];
        }
        return target;
    }

    
    public static void main(String[] args)
    {
        Main&lt;Integer, String&gt; mm = new Main&lt;&gt;();
        mm.foo(new String[] {&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;}, 
               new Integer[]{1, 2, 3, 4, 5, 6});
    }
}

Output

输出

[a, b, c, d]
[1, 2, 3, 4, 5, 6]
[a, b]
[1, 2, 3]
英文:

It is impossible to have overloaded functions which use generic types for their arguments because of the type erasure.

It should work if additional type information is provided as shown here.

However, the example below shows how the same function may be used for different generic types without explicit type information. It is also recommended to use @SuppressWarnings(&quot;unchecked&quot;) for assignValue.

Online demo

import java.util.*;

public class Main&lt;K, V&gt;
{
    public &lt;K, V&gt; void foo(K[] arrK, V[] arrV) {
        System.out.println(Arrays.toString(arrK));
        System.out.println(Arrays.toString(arrV));
        K[] resK = assignValue(arrK, 0, arrK.length/2, arrK.length/2);
        V[] resV = assignValue(arrV, 0, arrV.length/2, arrV.length/2);
        System.out.println(Arrays.toString(resK));
        System.out.println(Arrays.toString(resV));
    }
    
    @SuppressWarnings(&quot;unchecked&quot;)
    public &lt;T&gt; T[] assignValue(T[] value, int i, int counter, int size) {
        if(counter &gt; size) {
            return null;
        }
        T[] target = (T[]) new Object[size];
    
        for(int j = i; j &lt; counter; j++) {
            if(value[i] == null) {
                return null;
            }
            target[j] = value[j];
        }
        return target;
    }

    
    public static void main(String[] args)
    {
        Main&lt;Integer, String&gt; mm = new Main&lt;&gt;();
        mm.foo(new String[] {&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;}, 
               new Integer[]{1, 2, 3, 4, 5, 6});
    }
}

Output

[a, b, c, d]
[1, 2, 3, 4, 5, 6]
[a, b]
[1, 2, 3]

huangapple
  • 本文由 发表于 2020年8月13日 00:58:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63381365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定