Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何编写一个接受类型为x的数组和另一个与该数组类型相同的变量的方法_Java_Generics - Fatal编程技术网

Java 如何编写一个接受类型为x的数组和另一个与该数组类型相同的变量的方法

Java 如何编写一个接受类型为x的数组和另一个与该数组类型相同的变量的方法,java,generics,Java,Generics,我想写一个接受数组和其他东西的通用方法。每一种都可以是任何类型,但它们必须是相同的。我试过了,但是我仍然可以在方法中输入任何东西 public static <T> boolean arrayContains(T[] array, T object){ return Arrays.asList(array).contains(object); } 公共静态布尔数组内容(T[]数组,T对象){ 返回Arrays.asList(array).contains(object);

我想写一个接受数组和其他东西的通用方法。每一种都可以是任何类型,但它们必须是相同的。我试过了,但是我仍然可以在方法中输入任何东西

public static <T> boolean arrayContains(T[] array, T object){
    return Arrays.asList(array).contains(object);
}
公共静态布尔数组内容(T[]数组,T对象){
返回Arrays.asList(array).contains(object);
}
我可以使用
arrayContains(新字符串[]{“stuff”},new Pig())
调用此方法,但我只希望它接受
arrayContains(新字符串[]{“stuff”},更多stuff”)

接下来呢

public static <A, E extends A> boolean arrayContains(A[] array, E object){
    return Arrays.asList(array).contains(object);
}
公共静态布尔数组内容(A[]数组,E对象){
返回Arrays.asList(array).contains(object);
}

在这种情况下,第二个参数的类型必须扩展(或与之相同)数组元素的类型

您尝试执行的操作很棘手,因为任何数组(除了基本体数组)都是
对象[]
,因此,正如您所注意到的,该方法将始终接受任何数组和任何对象

解决这个问题的一种方法是传递一个显式的
对象,如下所示

public static <T> boolean arrayContains(T[] array, T object, Class<T> clazz)
但不是

arrayContains(new String[]{"stuff"}, new Pig(), String.class)

您需要提供多个参数化类型,然后在它们不匹配时执行某些操作

public static <T, S> boolean arrayContains(T[] array, S object){
    System.out.println("array.class: " + array.getClass().getComponentType().getName());
    System.out.println("object.class: " + object.getClass().getName());
    System.out.println("array.class == object.class: " + (array.getClass().getComponentType() == object.getClass()));

    // TODO: do something if the types don't match

    return Arrays.asList(array).contains(object);
}
公共静态布尔数组内容(T[]数组,S对象){
System.out.println(“array.class:+array.getClass().getComponentType().getName());
System.out.println(“object.class:+object.getClass().getName());
System.out.println(“array.class==object.class:”+(array.getClass().getComponentType()==object.getClass());
//TODO:如果类型不匹配,请执行某些操作
返回Arrays.asList(array).contains(object);
}
你不能

或者换句话说,任何数组和任何引用都已经满足您的要求,“类型为x的数组和另一个与数组类型相同的变量”,因为任何数组都是“类型为<代码>对象的数组”,并且任何引用都是同一类型(
对象

您想要的不是类型安全目的。假设,假设有语言特征来做你想做的事。它只能对参数表达式的编译时类型进行操作。但总有人能做到这一点:

Object[] foo = anyArrayExpression;
Object bar = anyReferenceExpression;
arrayContains(foo, bar);

(顺便说一句,它们都没有做任何可疑或不安全的事情。在Java中,上行操作总是100%安全和合法的。)

因此,任何数组和任何引用都可以始终传递给函数,而函数始终需要处理任何类型数组和任何类型对象的实际对象。所以你的功能一无所获


即使您将其限制为某些类型的子类型
X
,并且您的函数只接受
X[]
X
,但传入的引用所指向的对象的实际运行时类仍然可能是
Y[]
Z
,其中
Y
Z
X
的不相关子类型。这只是Java类型系统如何工作的一个事实。因此,无论您如何操作,您的函数始终必须处理数组的运行时组件类型可能与其他对象的运行时类无关。(唯一的例外是,如果
X
是final,因此它没有子类,但是您的限制将是毫无意义的,因为它通常都是真的。)

这就是我最后要做的

public static boolean arrayContains(Object[] array, Object object) {
        if (array.getClass().getComponentType() != object.getClass()) {
            throw new IllegalArgumentException("Type of array and object are not equal! " + array.getClass().getComponentType().getName() + " != " + object.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return Arrays.asList(array).contains(object);
    }

那么
arrayContains(T object,T[]array)
呢?问题是在您的情况下
T
变成
object
。除了显式地专门化类型之外,看不到任何解决方案。在这种情况下,
arrayContains
,这并不重要。它只会返回false,因为
字符串[]
不能包含
清管器
。但无论如何,在这种情况下,它是一个
对象,如上所述。这就是我的问题,我无意中为第二个参数传递了错误的类型,它永远不会返回true,编译器也不会捕获它。我先传递了一个包数组,然后传递了一个包字符串,然后我就不知道出了什么问题。然后我找到了答案,并决定为此编写自己的方法,这样我就不会再遇到同样的问题。我确实想使用Java 8我不想这样做,因为它只是添加了另一个占用时间的参数。实际上,我最终使用了它并测试了对象的类型。
arrayContains((Object[])anyArrayExpression, (Object)anyReferenceExpression);
public static boolean arrayContains(Object[] array, Object object) {
        if (array.getClass().getComponentType() != object.getClass()) {
            throw new IllegalArgumentException("Type of array and object are not equal! " + array.getClass().getComponentType().getName() + " != " + object.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return Arrays.asList(array).contains(object);
    }