How to write a method that takes an array of type x and another variable with the same type as the array

I would like to write a generic method that takes an array and something else. Each of them can be of any type, but they must be the same. I tried this, but I could still introduce anything to this method.

public static <T> boolean arrayContains(T[] array, T object){ return Arrays.asList(array).contains(object); } 

I can call this method with arrayContains(new String[]{"stuff"}, new Pig()) , but I want it to accept arrayContains(new String[]{"stuff"}, "more stuff")

+5
source share
5 answers

Here is what I did.

 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); } 
0
source

What you are trying to do is difficult because any array (except an array of primitives) is Object[] , as you noticed, the method will always accept any array and any object.

One way might be to pass an explicit Class object, for example

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

Then you could write

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

but not

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

You can not.

Or otherwise, any array and any reference already satisfies your requirement "an array of type x and another variable with the same type as the array", because any array is an "array of type Object " and any reference of the same type ( Object ).

What you want is not intended for security purposes. Think, hypothetically, that there is a language function to do what you want. It can only work with types of argument expressions at compile time. But someone can always do this:

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

or

 arrayContains((Object[])anyArrayExpression, (Object)anyReferenceExpression); 

(And by the way, none of them does anything suspicious or unsafe. An adult is always 100% safe and legal in Java.)

Thus, any array and any reference can always be passed to your function in any case, and your function should always process the actual objects like any type of array and any type object in any case. Thus, your function does not achieve anything.

Even if you restrict it to subtypes of some type X , and your function accepts only X[] and X , it may always be that the actual runtime class of the objects referenced in is Y[] and Z , where Y and Z are unrelated subtypes of X This is just a fact of how a system like Java works. That way, your function will always deal with the type of runtime component that is potentially not related to the runtime class of another object, no matter how you do it. (The only exception would be if X was final, so it has no subclasses, but then your restriction would be pointless, because it would be trivial always true.)

+2
source

What about the next one?

 public static <A, E extends A> boolean arrayContains(A[] array, E object){ return Arrays.asList(array).contains(object); } 

In this case, the type of the second argument must expand (or be the same) as the type of the elements of the array.

0
source

You need to provide several parameterized types, and then do something if they do not match.

 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); } 
-2
source

Source: https://habr.com/ru/post/1209553/


All Articles