As following, same AMF data can be decoded as ArrayList<?>, ArrayList<String>, String[].

// Construction of Data.
ArrayList<String> strings = new ArrayList<String>();
strings.add("Item001");
strings.add("Item002");
strings.add("Item003");
strings.add("Item004");
strings.add("Item005");

// How to encode.
byte[] amf = AmfUtil.encode(strings); // Encode as ArrayCollection.

// How to decode. (ArrayList<?>)
ArrayList<?> decoded1 = AmfUtil.decode(amf, ArrayList.class);

// How to decode. (ArrayList<String>)
ArrayList<String> decoded2 = AmfUtil.decode(amf,
    TypeUtil.getCollectionType(ArrayList.class, String.class));

// How to decode. (String[])
String[] decoded3 = AmfUtil.decode(amf, String[].class);

In this case, ArrayList<?> and ArrayList<String> examples are almost same.
But, I recommend ArrayList<String>’s way, because it is sure to be decoded as String.
(If elements can not be decoded as String, exception is thrown.)