Your code can't work. The generics just don't line up.
Let's say you have an array that is a combination of strings and arrays of strings. That cannot possibly be a T[] unless T is object, which isn't what you want (as that would mean you get a List<Object>. After all, If T is String, then your input array, which is defined as T[] in, is a String[] in, which cannot contain string arrays. After all, a String[] is not a subtype of String, for obvious reasons.
It is impossible to describe in terms of generics the concept of 'an array of Strings, or an array of arrays of Strings, or an array of arrays of arrays of Strings, and so forth'. So, generics have no place here. If you want that, all you can 'type' is 'an array whose component type is unknown and hybrid anyway', which is Object[] in java (this is co/contra-variance wise broken, but this is just part of the java spec: Variance on arrays is incorrect, known problem and not fixable).
This gets you a secondary issue: Generics are erased, and in that model you don't have an actual type to work with. In fact, because it is impossible to use generics to tell the compiler to do some type checking on the input array, there is nothing the compiler can do for you, so any type checking you want (and you clearly want that, you don't want to return a List of who knows what this is), will have to be done at runtime.
Unfortunately, it is impossible to do that, too - you can't check if at runtime if some object is, say, a Map<String, Integer>.
So, what you want is impossible.
It becomes possible if you're okay with this method being only able to do the job for reified types. That is, types that don't contain any <> themselves. So, if you want to take 'an array that contains a combination of "Map of string to integer" and "arrays of Maps of string to integer"', this method will not be able to do that and it is in fact completely impossible to do such a thing in java. But if you're okay with, say, "An array containing a combination of strings and arrays of strings" and want to turn that into a flattened-out list of strings, okay, that's possible.
It's complicated, though:
public <T> List<T> flattenArray(Class<T> type, Object[] in) {
if (type.isArray()) throw new IllegalArgumentException();
var out = new ArrayList<T>();
flattenArray0(type, in, out);
return out;
}
private <T> void flattenArray0(Class<T> type, Object[] in, List<T> out) {
for (Object a : in) {
if (a == null) {
out.add(null);
} else if (a.getClass().isArray()) {
flattenArray0(type, (Object[]) a, out);
} else {
out.add(type.cast(a));
}
}
}
In action:
Object[] test = new Object[3];
test[0] = "Hello";
test[1] = new String[] {"Foo", "Bar"};
Object[] threeDeep = new Object[2];
test[2] = threeDeep;
threeDeep[0] = "Goodbye";
threeDeep[1] = new String[] {"Baz"};
List<String> result = flattenArray(String.class, test);
System.out.println(result);
should print: ["Hello", "Foo", "Bar", "Goodbye", "Baz"].