Search code examples
javaarraylistgeneric-type-argument

Why ArrayList<String> get() returns Object not String in Java


While making an argument parser, I used ArrayList<String>.
Refering to this official Documentation, ArrayList<E>.get() should be returning E typed Objects, so ArrayList<String>.get() should be returning String Objects.

However, I am getting Object instead of String elements in this case.

enter image description here

import lombok.Data;

import java.util.ArrayList;

@Data
public class Argument<T> {
    public ArrayList<String> Args;
    public String Description;
    public Boolean Required;
    public Boolean HasValue;
    public T Value;
}
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

public class ArgumentParser {
    private ArrayList<Argument> argumentList_;

    public String ArgList() {
        StringBuilder builder = new StringBuilder(); 
        for (Argument argument : argumentList_) {

            //Here is the problem
            for (String arg : argument.Args) {
                builder.append(arg);
                builder.append(", ");
            }
        }
        //Delete Traling Comma
        builder.delete(builder.length());
        builder.delete(builder.length());

        return builder.toString();
    }
}

Is this situation

  1. A bug in IDE Environment (IntelliJ + Lombok)
  2. My code is making Java do this (Generic Typing)

Help me...


Solution

  • In the first piece of code Argument is defined to have a type parameter.

    public class Argument<T> {
        public ArrayList<String> Args;
    

    In the second piece of code Argument is used but the type argument is missing.

        private ArrayList<Argument> argumentList_;
        // ...
            for (Argument argument : argumentList_) {
    

    ArrayList<Argument> is a rare type (less frequently(?) known as a partial raw type - a type with a raw type argument). The behaviour of which is odd.

    The easy fix is a wildcard.

        private ArrayList<Argument<?>> argumentList_;
        // ...
            for (Argument<?> argument : argumentList_) {