What is a raw type and why shouldn't we use it?











up vote
556
down vote

favorite
256












Questions:




  • What are raw types in Java, and why do I often hear that they shouldn't be used in new code?

  • What is the alternative if we can't use raw types, and how is it better?










share|improve this question
























  • the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
    – SuperStar
    Apr 2 '13 at 10:04






  • 1




    Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
    – Jesper
    May 23 '16 at 8:07















up vote
556
down vote

favorite
256












Questions:




  • What are raw types in Java, and why do I often hear that they shouldn't be used in new code?

  • What is the alternative if we can't use raw types, and how is it better?










share|improve this question
























  • the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
    – SuperStar
    Apr 2 '13 at 10:04






  • 1




    Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
    – Jesper
    May 23 '16 at 8:07













up vote
556
down vote

favorite
256









up vote
556
down vote

favorite
256






256





Questions:




  • What are raw types in Java, and why do I often hear that they shouldn't be used in new code?

  • What is the alternative if we can't use raw types, and how is it better?










share|improve this question















Questions:




  • What are raw types in Java, and why do I often hear that they shouldn't be used in new code?

  • What is the alternative if we can't use raw types, and how is it better?







java generics raw-types






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 22 '17 at 16:13









Taryn

188k45286351




188k45286351










asked May 5 '10 at 2:48









polygenelubricants

280k101503591




280k101503591












  • the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
    – SuperStar
    Apr 2 '13 at 10:04






  • 1




    Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
    – Jesper
    May 23 '16 at 8:07


















  • the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
    – SuperStar
    Apr 2 '13 at 10:04






  • 1




    Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
    – Jesper
    May 23 '16 at 8:07
















the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
– SuperStar
Apr 2 '13 at 10:04




the java tutorials still use the JComboBox that causes this warning. Which version of the combobox will not cause this warning ? docs.oracle.com/javase/tutorial/uiswing/components/…
– SuperStar
Apr 2 '13 at 10:04




1




1




Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
– Jesper
May 23 '16 at 8:07




Note that the reason why raw types exist is for backwards compatibility with Java 1.4 and older, which did not have generics at all.
– Jesper
May 23 '16 at 8:07












14 Answers
14






active

oldest

votes

















up vote
647
down vote













What is a raw type?



The Java Language Specification defines a raw type as follows:



JLS 4.8 Raw Types




A raw type is defined to be one of:




  • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.


  • An array type whose element type is a raw type.


  • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.





Here's an example to illustrate:



public class MyType<E> {
class Inner { }
static class Nested { }

public static void main(String args) {
MyType mt; // warning: MyType is a raw type
MyType.Inner inn; // warning: MyType.Inner is a raw type

MyType.Nested nest; // no warning: not parameterized type
MyType<Object> mt1; // no warning: type parameter given
MyType<?> mt2; // no warning: type parameter given (wildcard OK!)
}
}


Here, MyType<E> is a parameterized type (JLS 4.5). It is common to colloquially refer to this type as simply MyType for short, but technically the name is MyType<E>.



mt has a raw type (and generates a compilation warning) by the first bullet point in the above definition; inn also has a raw type by the third bullet point.



MyType.Nested is not a parameterized type, even though it's a member type of a parameterized type MyType<E>, because it's static.



mt1, and mt2 are both declared with actual type parameters, so they're not raw types.





What's so special about raw types?



Essentially, raw types behaves just like they were before generics were introduced. That is, the following is entirely legal at compile-time.



List names = new ArrayList(); // warning: raw type!
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // not a compilation error!


The above code runs just fine, but suppose you also have the following:



for (Object o : names) {
String name = (String) o;
System.out.println(name);
} // throws ClassCastException!
// java.lang.Boolean cannot be cast to java.lang.String


Now we run into trouble at run-time, because names contains something that isn't an instanceof String.



Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names. Even better, though is NOT to use a raw type and let the compiler do all the work for you, harnessing the power of Java generics.



List<String> names = new ArrayList<String>();
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // compilation error!


Of course, if you DO want names to allow a Boolean, then you can declare it as List<Object> names, and the above code would compile.



See also




  • Java Tutorials/Generics




How's a raw type different from using <Object> as type parameters?



The following is a quote from Effective Java 2nd Edition, Item 23: Don't use raw types in new code:




Just what is the difference between the raw type List and the parameterized type List<Object>? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List<String> to a parameter of type List, you can't pass it to a parameter of type List<Object>. There are subtyping rules for generics, and List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List<Object>.




To illustrate the point, consider the following method which takes a List<Object> and appends a new Object().



void appendNewObject(List<Object> list) {
list.add(new Object());
}


Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:



List<String> names = new ArrayList<String>();
appendNewObject(names); // compilation error!


If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.



See also




  • What is the difference between <E extends Number> and <Number>?

  • java generics (not) covariance




How's a raw type different from using <?> as a type parameter?



List<Object>, List<String>, etc are all List<?>, so it may be tempting to just say that they're just List instead. However, there is a major difference: since a List<E> defines only add(E), you can't add just any arbitrary object to a List<?>. On the other hand, since the raw type List does not have type safety, you can add just about anything to a List.



Consider the following variation of the previous snippet:



static void appendNewObject(List<?> list) {
list.add(new Object()); // compilation error!
}
//...

List<String> names = new ArrayList<String>();
appendNewObject(names); // this part is fine!


The compiler did a wonderful job of protecting you from potentially violating the type invariance of the List<?>! If you had declared the parameter as the raw type List list, then the code would compile, and you'd violate the type invariant of List<String> names.





A raw type is the erasure of that type



Back to JLS 4.8:




It is possible to use as a type the erasure of a parameterized type or the erasure of an array type whose element type is a parameterized type. Such a type is called a raw type.



[...]



The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.



The type of a constructor, instance method, or non-static field of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.




In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.



Take the following example:



class MyType<E> {
List<String> getNames() {
return Arrays.asList("John", "Mary");
}

public static void main(String args) {
MyType rawType = new MyType();
// unchecked warning!
// required: List<String> found: List
List<String> names = rawType.getNames();
// compilation error!
// incompatible types: Object cannot be converted to String
for (String str : rawType.getNames())
System.out.print(str);
}
}


When we use the raw MyType, getNames becomes erased as well, so that it returns a raw List!



JLS 4.6 continues to explain the following:




Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.



The return type of a method and the type parameters of a generic method or constructor also undergo erasure if the method or constructor's signature is erased.



The erasure of the signature of a generic method has no type parameters.




The following bug report contains some thoughts from Maurizio Cimadamore, a compiler dev, and Alex Buckley, one of the authors of the JLS, on why this sort of behavior ought to occur: https://bugs.openjdk.java.net/browse/JDK-6400189. (In short, it makes the specification simpler.)





If it's unsafe, why is it allowed to use a raw type?



Here's another quote from JLS 4.8:




The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




Effective Java 2nd Edition also has this to add:




Given that you shouldn't use raw types, why did the language designers allow them? To provide compatibility.



The Java platform was about to enter its second decade when generics were introduced, and there was an enormous amount of Java code in existence that did not use generics. It was deemed critical that all this code remains legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.




In summary, raw types should NEVER be used in new code. You should always use parameterized types.





Are there no exceptions?



Unfortunately, because Java generics are non-reified, there are two exceptions where raw types must be used in new code:




  • Class literals, e.g. List.class, not List<String>.class


  • instanceof operand, e.g. o instanceof Set, not o instanceof Set<String>


See also




  • Why is Collection<String>.class Illegal?






share|improve this answer



















  • 13




    What do you mean that, "Java generics are non-reified"?
    – Carl G
    Dec 15 '12 at 20:07






  • 6




    For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
    – Paul Bellora
    May 20 '13 at 4:20






  • 8




    /me Slow claps at end of answer
    – Dan Grahn
    Jun 10 '14 at 18:56






  • 6




    "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
    – Erick G. Hagstrom
    Jul 21 '15 at 18:24






  • 2




    @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
    – Radiodef
    Apr 19 '16 at 14:09


















up vote
52
down vote














What are raw types in Java, and why do I often hear that they shouldn't be used in new code?




Raw-types are ancient history of the Java language. In the beginning there were Collections and they held Objects nothing more and nothing less. Every operation on Collections required casts from Object to the desired type.



List aList = new ArrayList();
String s = "Hello World!";
aList.add(s);
String c = (String)aList.get(0);


While this worked most of the time, errors did happen



List aNumberList = new ArrayList();
String one = "1";//Number one
aNumberList.add(one);
Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here


The old typeless collections could not enforce type-safety so the programmer had to remember what he stored within a collection.

Generics where invented to get around this limitation, the developer would declare the stored type once and the compiler would do it instead.



List<String> aNumberList = new ArrayList<String>();
aNumberList.add("one");
Integer iOne = aNumberList.get(0);//Compile time error
String sOne = aNumberList.get(0);//works fine


For Comparison:



// Old style collections now known as raw types
List aList = new ArrayList(); //Could contain anything
// New style collections with Generics
List<String> aList = new ArrayList<String>(); //Contains only Strings


More complex the Compareable interface:



//raw, not type save can compare with Other classes
class MyCompareAble implements CompareAble
{
int id;
public int compareTo(Object other)
{return this.id - ((MyCompareAble)other).id;}
}
//Generic
class MyCompareAble implements CompareAble<MyCompareAble>
{
int id;
public int compareTo(MyCompareAble other)
{return this.id - other.id;}
}


Note that it is impossible to implement the CompareAble interface with compareTo(MyCompareAble) with raw types.
Why you should not use them:




  • Any Object stored in a Collection has to be cast before it can be used

  • Using generics enables compile time checks

  • Using raw types is the same as storing each value as Object


What the compiler does:
Generics are backward compatible, they use the same java classes as the raw types do. The magic happens mostly at compile time.



List<String> someStrings = new ArrayList<String>();
someStrings.add("one");
String one = someStrings.get(0);


Will be compiled as:



List someStrings = new ArrayList();
someStrings.add("one");
String one = (String)someStrings.get(0);


This is the same code you would write if you used the raw types directly. Thought I'm not sure what happens with the CompareAble interface, I guess that it creates two compareTo functions, one taking a MyCompareAble and the other taking an Object and passing it to the first after casting it.



What are the alternatives to raw types: Use generics






share|improve this answer






























    up vote
    22
    down vote













    A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



    public class Box<T> {
    public void set(T t) { /* ... */ }
    // ...
    }


    To create a parameterized type of Box<T>, you supply an actual type argument for the formal type parameter T:



    Box<Integer> intBox = new Box<>();


    If the actual type argument is omitted, you create a raw type of Box<T>:



    Box rawBox = new Box();


    Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type.



    Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:



    Box<String> stringBox = new Box<>();
    Box rawBox = stringBox; // OK


    But if you assign a raw type to a parameterized type, you get a warning:



    Box rawBox = new Box();           // rawBox is a raw type of Box<T>
    Box<Integer> intBox = rawBox; // warning: unchecked conversion


    You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:



    Box<String> stringBox = new Box<>();
    Box rawBox = stringBox;
    rawBox.set(8); // warning: unchecked invocation to set(T)


    The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.



    The Type Erasure section has more information on how the Java compiler uses raw types.



    Unchecked Error Messages



    As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:




    Note: Example.java uses unchecked or unsafe operations.



    Note: Recompile with -Xlint:unchecked for details.




    This can happen when using an older API that operates on raw types, as shown in the following example:



    public class WarningDemo {
    public static void main(String args){
    Box<Integer> bi;
    bi = createBox();
    }

    static Box createBox(){
    return new Box();
    }
    }


    The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.



    Recompiling the previous example with -Xlint:unchecked reveals the following additional information:



    WarningDemo.java:4: warning: [unchecked] unchecked conversion
    found : Box
    required: Box<java.lang.Integer>
    bi = createBox();
    ^
    1 warning


    To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.



    Original source: Java Tutorials






    share|improve this answer






























      up vote
      17
      down vote













       private static List<String> list = new ArrayList<String>();


      You should specify the type-parameter.



      The warning advises that types that are defined to support generics should be parameterized, rather than using their raw form.



      List is defined to support generics: public class List<E>. This allows many type-safe operations, that are checked compile-time.






      share|improve this answer

















      • 2




        Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
        – Ian Campbell
        Oct 10 '14 at 14:03


















      up vote
      14
      down vote













      A "raw" type in Java is a class which is non-generic and deals with "raw" Objects, rather than type-safe generic type parameters.



      For example, before Java generics was available, you would use a collection class like this:



      LinkedList list = new LinkedList();
      list.add(new MyObject());
      MyObject myObject = (MyObject)list.get(0);


      When you add your object to the list, it doesn't care what type of object it is, and when you get it from the list, you have to explicitly cast it to the type you are expecting.



      Using generics, you remove the "unknown" factor, because you must explicitly specify which type of objects can go in the list:



      LinkedList<MyObject> list = new LinkedList<MyObject>();
      list.add(new MyObject());
      MyObject myObject = list.get(0);


      Notice that with generics you don't have to cast the object coming from the get call, the collection is pre-defined to only work with MyObject. This very fact is the main driving factor for generics. It changes a source of runtime errors into something that can be checked at compile time.






      share|improve this answer

















      • 3




        More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
        – John Flatness
        May 5 '10 at 3:10










      • @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
        – polygenelubricants
        May 5 '10 at 5:08


















      up vote
      10
      down vote













      What is a raw type and why do I often hear that they shouldn't be used in new code?



      A "raw type" is the use of a generic class without specifying a type argument(s) for its parameterized type(s), e.g. using List instead of List<String>. When generics were introduced into Java, several classes were updated to use generics. Using these class as a "raw type" (without specifying a type argument) allowed legacy code to still compile.



      "Raw types" are used for backwards compatibility. Their use in new code is not recommended because using the generic class with a type argument allows for stronger typing, which in turn may improve code understandability and lead to catching potential problems earlier.



      What is the alternative if we can't use raw types, and how is it better?



      The preferred alternative is to use generic classes as intended - with a suitable type argument (e.g. List<String>). This allows the programmer to specify types more specifically, conveys more meaning to future maintainers about the intended use of a variable or data structure, and it allows compiler to enforce better type-safety. These advantages together may improve code quality and help prevent the introduction of some coding errors.



      For example, for a method where the programmer wants to ensure a List variable called 'names' contains only Strings:



      List<String> names = new ArrayList<String>();
      names.add("John"); // OK
      names.add(new Integer(1)); // compile error





      share|improve this answer

















      • 1




        Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
        – Bert F
        May 5 '10 at 4:38






      • 1




        yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
        – polygenelubricants
        May 5 '10 at 5:02








      • 1




        @polygenelubricants I noticed - we hit some of the same questions :-)
        – Bert F
        May 5 '10 at 5:17






      • 1




        this answer is much better than the accepted one - concise and simple
        – ha9u63ar
        Aug 2 '16 at 11:47






      • 1




        @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
        – displayName
        Aug 7 '17 at 15:02


















      up vote
      10
      down vote













      The compiler wants you to write this:



      private static List<String> list = new ArrayList<String>();


      because otherwise, you could add any type you like into list, making the instantiation as new ArrayList<String>() pointless. Java generics are a compile-time feature only, so an object created with new ArrayList<String>() will happily accept Integer or JFrame elements if assigned to a reference of the "raw type" List - the object itself knows nothing about what types it's supposed to contain, only the compiler does.






      share|improve this answer




























        up vote
        9
        down vote













        Here I am Considering multiple cases through which you can clearify the concept



        1. ArrayList<String> arr = new ArrayList<String>();
        2. ArrayList<String> arr = new ArrayList();
        3. ArrayList arr = new ArrayList<String>();


        Case 1



        ArrayList<String> arr it is a ArrayList reference variable with type String which reference to a ArralyList Object of Type String. It means it can hold only String type Object.



        It is a Strict to String not a Raw Type so, It will never raise an warning .



            arr.add("hello");// alone statement will compile successfully and no warning.

        arr.add(23); //prone to compile time error.
        //error: no suitable method found for add(int)


        Case 2



        In this case ArrayList<String> arr is a strict type but your Object new ArrayList(); is a raw type.



            arr.add("hello"); //alone this compile but raise the warning.
        arr.add(23); //again prone to compile time error.
        //error: no suitable method found for add(int)


        here arr is a Strict type. So, It will raise compile time error when adding a integer.




        Warning :- A Raw Type Object is referenced to a Strict type Referenced Variable of ArrayList.




        Case 3



        In this case ArrayList arr is a raw type but your Object new ArrayList<String>(); is a Strict type.



            arr.add("hello");  
        arr.add(23); //compiles fine but raise the warning.


        It will add any type of Object into it because arr is a Raw Type.




        Warning :- A Strict Type Object is referenced to a raw type referenced Variable.







        share|improve this answer






























          up vote
          8
          down vote













          A raw-type is the a lack of a type parameter when using a generic type.



          Raw-type should not be used because it could cause runtime errors, like inserting a double into what was supposed to be a Set of ints.



          Set set = new HashSet();
          set.add(3.45); //ok


          When retrieving the stuff from the Set, you don't know what is coming out. Let's assume that you expect it to be all ints, you are casting it to Integer; exception at runtime when the double 3.45 comes along.



          With a type parameter added to your Set, you will get a compile error at once. This preemptive error lets you fix the problem before something blows up during runtime (thus saving on time and effort).



          Set<Integer> set = new HashSet<Integer>();
          set.add(3.45); //NOT ok.





          share|improve this answer






























            up vote
            4
            down vote













            What is saying is that your list is a List of unespecified objects. That is that Java does not know what kind of objects are inside the list. Then when you want to iterate the list you have to cast every element, to be able to access the properties of that element (in this case, String).



            In general is a better idea to parametrize the collections, so you don't have conversion problems, you will only be able to add elements of the parametrized type and your editor will offer you the appropiate methods to select.



            private static List<String> list = new ArrayList<String>();





            share|improve this answer




























              up vote
              4
              down vote













              tutorial page.



              A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



              public class Box<T> {
              public void set(T t) { /* ... */ }
              // ...
              }


              To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:



              Box<Integer> intBox = new Box<>();


              If the actual type argument is omitted, you create a raw type of Box:



              Box rawBox = new Box();





              share|improve this answer






























                up vote
                4
                down vote













                Here's another case where raw types will bite you:



                public class StrangeClass<T> {
                @SuppressWarnings("unchecked")
                public <X> X getSomethingElse() {
                return (X)"Testing something else!";
                }

                public static void main(String args) {
                final StrangeClass<String> withGeneric = new StrangeClass<>();
                final StrangeClass withoutGeneric = new StrangeClass();
                final String value1,
                value2;

                // Compiles
                value1 = withGeneric.getSomethingElse();

                // Produces compile error:
                // incompatible types: java.lang.Object cannot be converted to java.lang.String
                value2 = withoutGeneric.getSomethingElse();
                }
                }


                As was mentioned in the accepted answer, you lose all support for generics within the code of the raw type. Every type parameter is converted to its erasure (which in the above example is just Object).






                share|improve this answer






























                  up vote
                  1
                  down vote













                  I found this page after doing some sample exercises and having the exact same puzzlement.



                  ============== I went from this code as provide by the sample ===============



                  public static void main(String args) throws IOException {

                  Map wordMap = new HashMap();
                  if (args.length > 0) {
                  for (int i = 0; i < args.length; i++) {
                  countWord(wordMap, args[i]);
                  }
                  } else {
                  getWordFrequency(System.in, wordMap);
                  }
                  for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
                  Map.Entry entry = (Map.Entry) i.next();
                  System.out.println(entry.getKey() + " :t" + entry.getValue());
                  }


                  ====================== To This code ========================



                  public static void main(String args) throws IOException {
                  // replace with TreeMap to get them sorted by name
                  Map<String, Integer> wordMap = new HashMap<String, Integer>();
                  if (args.length > 0) {
                  for (int i = 0; i < args.length; i++) {
                  countWord(wordMap, args[i]);
                  }
                  } else {
                  getWordFrequency(System.in, wordMap);
                  }
                  for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
                  Entry<String, Integer> entry = i.next();
                  System.out.println(entry.getKey() + " :t" + entry.getValue());
                  }

                  }


                  ===============================================================================



                  It may be safer but took 4 hours to demuddle the philosophy...






                  share|improve this answer






























                    up vote
                    0
                    down vote













                    Raw types are fine when they express what you want to express.



                    For example, a deserialisation function might return a List, but it doesn't know the list's element type. So List is the appropriate return type here.






                    share|improve this answer





















                    • You can use ? as type parameter
                      – Dániel Kis
                      Dec 27 '17 at 19:29










                    • Yes, but that is more to type and I am against typing more. :)
                      – Stefan Reich
                      Dec 31 '17 at 18:37










                    protected by Luiggi Mendoza Oct 12 '13 at 17:37



                    Thank you for your interest in this question.
                    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                    Would you like to answer one of these unanswered questions instead?














                    14 Answers
                    14






                    active

                    oldest

                    votes








                    14 Answers
                    14






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes








                    up vote
                    647
                    down vote













                    What is a raw type?



                    The Java Language Specification defines a raw type as follows:



                    JLS 4.8 Raw Types




                    A raw type is defined to be one of:




                    • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.


                    • An array type whose element type is a raw type.


                    • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.





                    Here's an example to illustrate:



                    public class MyType<E> {
                    class Inner { }
                    static class Nested { }

                    public static void main(String args) {
                    MyType mt; // warning: MyType is a raw type
                    MyType.Inner inn; // warning: MyType.Inner is a raw type

                    MyType.Nested nest; // no warning: not parameterized type
                    MyType<Object> mt1; // no warning: type parameter given
                    MyType<?> mt2; // no warning: type parameter given (wildcard OK!)
                    }
                    }


                    Here, MyType<E> is a parameterized type (JLS 4.5). It is common to colloquially refer to this type as simply MyType for short, but technically the name is MyType<E>.



                    mt has a raw type (and generates a compilation warning) by the first bullet point in the above definition; inn also has a raw type by the third bullet point.



                    MyType.Nested is not a parameterized type, even though it's a member type of a parameterized type MyType<E>, because it's static.



                    mt1, and mt2 are both declared with actual type parameters, so they're not raw types.





                    What's so special about raw types?



                    Essentially, raw types behaves just like they were before generics were introduced. That is, the following is entirely legal at compile-time.



                    List names = new ArrayList(); // warning: raw type!
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // not a compilation error!


                    The above code runs just fine, but suppose you also have the following:



                    for (Object o : names) {
                    String name = (String) o;
                    System.out.println(name);
                    } // throws ClassCastException!
                    // java.lang.Boolean cannot be cast to java.lang.String


                    Now we run into trouble at run-time, because names contains something that isn't an instanceof String.



                    Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names. Even better, though is NOT to use a raw type and let the compiler do all the work for you, harnessing the power of Java generics.



                    List<String> names = new ArrayList<String>();
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // compilation error!


                    Of course, if you DO want names to allow a Boolean, then you can declare it as List<Object> names, and the above code would compile.



                    See also




                    • Java Tutorials/Generics




                    How's a raw type different from using <Object> as type parameters?



                    The following is a quote from Effective Java 2nd Edition, Item 23: Don't use raw types in new code:




                    Just what is the difference between the raw type List and the parameterized type List<Object>? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List<String> to a parameter of type List, you can't pass it to a parameter of type List<Object>. There are subtyping rules for generics, and List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List<Object>.




                    To illustrate the point, consider the following method which takes a List<Object> and appends a new Object().



                    void appendNewObject(List<Object> list) {
                    list.add(new Object());
                    }


                    Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:



                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // compilation error!


                    If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.



                    See also




                    • What is the difference between <E extends Number> and <Number>?

                    • java generics (not) covariance




                    How's a raw type different from using <?> as a type parameter?



                    List<Object>, List<String>, etc are all List<?>, so it may be tempting to just say that they're just List instead. However, there is a major difference: since a List<E> defines only add(E), you can't add just any arbitrary object to a List<?>. On the other hand, since the raw type List does not have type safety, you can add just about anything to a List.



                    Consider the following variation of the previous snippet:



                    static void appendNewObject(List<?> list) {
                    list.add(new Object()); // compilation error!
                    }
                    //...

                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // this part is fine!


                    The compiler did a wonderful job of protecting you from potentially violating the type invariance of the List<?>! If you had declared the parameter as the raw type List list, then the code would compile, and you'd violate the type invariant of List<String> names.





                    A raw type is the erasure of that type



                    Back to JLS 4.8:




                    It is possible to use as a type the erasure of a parameterized type or the erasure of an array type whose element type is a parameterized type. Such a type is called a raw type.



                    [...]



                    The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.



                    The type of a constructor, instance method, or non-static field of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.




                    In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.



                    Take the following example:



                    class MyType<E> {
                    List<String> getNames() {
                    return Arrays.asList("John", "Mary");
                    }

                    public static void main(String args) {
                    MyType rawType = new MyType();
                    // unchecked warning!
                    // required: List<String> found: List
                    List<String> names = rawType.getNames();
                    // compilation error!
                    // incompatible types: Object cannot be converted to String
                    for (String str : rawType.getNames())
                    System.out.print(str);
                    }
                    }


                    When we use the raw MyType, getNames becomes erased as well, so that it returns a raw List!



                    JLS 4.6 continues to explain the following:




                    Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.



                    The return type of a method and the type parameters of a generic method or constructor also undergo erasure if the method or constructor's signature is erased.



                    The erasure of the signature of a generic method has no type parameters.




                    The following bug report contains some thoughts from Maurizio Cimadamore, a compiler dev, and Alex Buckley, one of the authors of the JLS, on why this sort of behavior ought to occur: https://bugs.openjdk.java.net/browse/JDK-6400189. (In short, it makes the specification simpler.)





                    If it's unsafe, why is it allowed to use a raw type?



                    Here's another quote from JLS 4.8:




                    The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




                    Effective Java 2nd Edition also has this to add:




                    Given that you shouldn't use raw types, why did the language designers allow them? To provide compatibility.



                    The Java platform was about to enter its second decade when generics were introduced, and there was an enormous amount of Java code in existence that did not use generics. It was deemed critical that all this code remains legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.




                    In summary, raw types should NEVER be used in new code. You should always use parameterized types.





                    Are there no exceptions?



                    Unfortunately, because Java generics are non-reified, there are two exceptions where raw types must be used in new code:




                    • Class literals, e.g. List.class, not List<String>.class


                    • instanceof operand, e.g. o instanceof Set, not o instanceof Set<String>


                    See also




                    • Why is Collection<String>.class Illegal?






                    share|improve this answer



















                    • 13




                      What do you mean that, "Java generics are non-reified"?
                      – Carl G
                      Dec 15 '12 at 20:07






                    • 6




                      For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                      – Paul Bellora
                      May 20 '13 at 4:20






                    • 8




                      /me Slow claps at end of answer
                      – Dan Grahn
                      Jun 10 '14 at 18:56






                    • 6




                      "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                      – Erick G. Hagstrom
                      Jul 21 '15 at 18:24






                    • 2




                      @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                      – Radiodef
                      Apr 19 '16 at 14:09















                    up vote
                    647
                    down vote













                    What is a raw type?



                    The Java Language Specification defines a raw type as follows:



                    JLS 4.8 Raw Types




                    A raw type is defined to be one of:




                    • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.


                    • An array type whose element type is a raw type.


                    • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.





                    Here's an example to illustrate:



                    public class MyType<E> {
                    class Inner { }
                    static class Nested { }

                    public static void main(String args) {
                    MyType mt; // warning: MyType is a raw type
                    MyType.Inner inn; // warning: MyType.Inner is a raw type

                    MyType.Nested nest; // no warning: not parameterized type
                    MyType<Object> mt1; // no warning: type parameter given
                    MyType<?> mt2; // no warning: type parameter given (wildcard OK!)
                    }
                    }


                    Here, MyType<E> is a parameterized type (JLS 4.5). It is common to colloquially refer to this type as simply MyType for short, but technically the name is MyType<E>.



                    mt has a raw type (and generates a compilation warning) by the first bullet point in the above definition; inn also has a raw type by the third bullet point.



                    MyType.Nested is not a parameterized type, even though it's a member type of a parameterized type MyType<E>, because it's static.



                    mt1, and mt2 are both declared with actual type parameters, so they're not raw types.





                    What's so special about raw types?



                    Essentially, raw types behaves just like they were before generics were introduced. That is, the following is entirely legal at compile-time.



                    List names = new ArrayList(); // warning: raw type!
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // not a compilation error!


                    The above code runs just fine, but suppose you also have the following:



                    for (Object o : names) {
                    String name = (String) o;
                    System.out.println(name);
                    } // throws ClassCastException!
                    // java.lang.Boolean cannot be cast to java.lang.String


                    Now we run into trouble at run-time, because names contains something that isn't an instanceof String.



                    Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names. Even better, though is NOT to use a raw type and let the compiler do all the work for you, harnessing the power of Java generics.



                    List<String> names = new ArrayList<String>();
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // compilation error!


                    Of course, if you DO want names to allow a Boolean, then you can declare it as List<Object> names, and the above code would compile.



                    See also




                    • Java Tutorials/Generics




                    How's a raw type different from using <Object> as type parameters?



                    The following is a quote from Effective Java 2nd Edition, Item 23: Don't use raw types in new code:




                    Just what is the difference between the raw type List and the parameterized type List<Object>? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List<String> to a parameter of type List, you can't pass it to a parameter of type List<Object>. There are subtyping rules for generics, and List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List<Object>.




                    To illustrate the point, consider the following method which takes a List<Object> and appends a new Object().



                    void appendNewObject(List<Object> list) {
                    list.add(new Object());
                    }


                    Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:



                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // compilation error!


                    If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.



                    See also




                    • What is the difference between <E extends Number> and <Number>?

                    • java generics (not) covariance




                    How's a raw type different from using <?> as a type parameter?



                    List<Object>, List<String>, etc are all List<?>, so it may be tempting to just say that they're just List instead. However, there is a major difference: since a List<E> defines only add(E), you can't add just any arbitrary object to a List<?>. On the other hand, since the raw type List does not have type safety, you can add just about anything to a List.



                    Consider the following variation of the previous snippet:



                    static void appendNewObject(List<?> list) {
                    list.add(new Object()); // compilation error!
                    }
                    //...

                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // this part is fine!


                    The compiler did a wonderful job of protecting you from potentially violating the type invariance of the List<?>! If you had declared the parameter as the raw type List list, then the code would compile, and you'd violate the type invariant of List<String> names.





                    A raw type is the erasure of that type



                    Back to JLS 4.8:




                    It is possible to use as a type the erasure of a parameterized type or the erasure of an array type whose element type is a parameterized type. Such a type is called a raw type.



                    [...]



                    The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.



                    The type of a constructor, instance method, or non-static field of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.




                    In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.



                    Take the following example:



                    class MyType<E> {
                    List<String> getNames() {
                    return Arrays.asList("John", "Mary");
                    }

                    public static void main(String args) {
                    MyType rawType = new MyType();
                    // unchecked warning!
                    // required: List<String> found: List
                    List<String> names = rawType.getNames();
                    // compilation error!
                    // incompatible types: Object cannot be converted to String
                    for (String str : rawType.getNames())
                    System.out.print(str);
                    }
                    }


                    When we use the raw MyType, getNames becomes erased as well, so that it returns a raw List!



                    JLS 4.6 continues to explain the following:




                    Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.



                    The return type of a method and the type parameters of a generic method or constructor also undergo erasure if the method or constructor's signature is erased.



                    The erasure of the signature of a generic method has no type parameters.




                    The following bug report contains some thoughts from Maurizio Cimadamore, a compiler dev, and Alex Buckley, one of the authors of the JLS, on why this sort of behavior ought to occur: https://bugs.openjdk.java.net/browse/JDK-6400189. (In short, it makes the specification simpler.)





                    If it's unsafe, why is it allowed to use a raw type?



                    Here's another quote from JLS 4.8:




                    The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




                    Effective Java 2nd Edition also has this to add:




                    Given that you shouldn't use raw types, why did the language designers allow them? To provide compatibility.



                    The Java platform was about to enter its second decade when generics were introduced, and there was an enormous amount of Java code in existence that did not use generics. It was deemed critical that all this code remains legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.




                    In summary, raw types should NEVER be used in new code. You should always use parameterized types.





                    Are there no exceptions?



                    Unfortunately, because Java generics are non-reified, there are two exceptions where raw types must be used in new code:




                    • Class literals, e.g. List.class, not List<String>.class


                    • instanceof operand, e.g. o instanceof Set, not o instanceof Set<String>


                    See also




                    • Why is Collection<String>.class Illegal?






                    share|improve this answer



















                    • 13




                      What do you mean that, "Java generics are non-reified"?
                      – Carl G
                      Dec 15 '12 at 20:07






                    • 6




                      For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                      – Paul Bellora
                      May 20 '13 at 4:20






                    • 8




                      /me Slow claps at end of answer
                      – Dan Grahn
                      Jun 10 '14 at 18:56






                    • 6




                      "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                      – Erick G. Hagstrom
                      Jul 21 '15 at 18:24






                    • 2




                      @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                      – Radiodef
                      Apr 19 '16 at 14:09













                    up vote
                    647
                    down vote










                    up vote
                    647
                    down vote









                    What is a raw type?



                    The Java Language Specification defines a raw type as follows:



                    JLS 4.8 Raw Types




                    A raw type is defined to be one of:




                    • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.


                    • An array type whose element type is a raw type.


                    • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.





                    Here's an example to illustrate:



                    public class MyType<E> {
                    class Inner { }
                    static class Nested { }

                    public static void main(String args) {
                    MyType mt; // warning: MyType is a raw type
                    MyType.Inner inn; // warning: MyType.Inner is a raw type

                    MyType.Nested nest; // no warning: not parameterized type
                    MyType<Object> mt1; // no warning: type parameter given
                    MyType<?> mt2; // no warning: type parameter given (wildcard OK!)
                    }
                    }


                    Here, MyType<E> is a parameterized type (JLS 4.5). It is common to colloquially refer to this type as simply MyType for short, but technically the name is MyType<E>.



                    mt has a raw type (and generates a compilation warning) by the first bullet point in the above definition; inn also has a raw type by the third bullet point.



                    MyType.Nested is not a parameterized type, even though it's a member type of a parameterized type MyType<E>, because it's static.



                    mt1, and mt2 are both declared with actual type parameters, so they're not raw types.





                    What's so special about raw types?



                    Essentially, raw types behaves just like they were before generics were introduced. That is, the following is entirely legal at compile-time.



                    List names = new ArrayList(); // warning: raw type!
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // not a compilation error!


                    The above code runs just fine, but suppose you also have the following:



                    for (Object o : names) {
                    String name = (String) o;
                    System.out.println(name);
                    } // throws ClassCastException!
                    // java.lang.Boolean cannot be cast to java.lang.String


                    Now we run into trouble at run-time, because names contains something that isn't an instanceof String.



                    Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names. Even better, though is NOT to use a raw type and let the compiler do all the work for you, harnessing the power of Java generics.



                    List<String> names = new ArrayList<String>();
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // compilation error!


                    Of course, if you DO want names to allow a Boolean, then you can declare it as List<Object> names, and the above code would compile.



                    See also




                    • Java Tutorials/Generics




                    How's a raw type different from using <Object> as type parameters?



                    The following is a quote from Effective Java 2nd Edition, Item 23: Don't use raw types in new code:




                    Just what is the difference between the raw type List and the parameterized type List<Object>? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List<String> to a parameter of type List, you can't pass it to a parameter of type List<Object>. There are subtyping rules for generics, and List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List<Object>.




                    To illustrate the point, consider the following method which takes a List<Object> and appends a new Object().



                    void appendNewObject(List<Object> list) {
                    list.add(new Object());
                    }


                    Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:



                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // compilation error!


                    If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.



                    See also




                    • What is the difference between <E extends Number> and <Number>?

                    • java generics (not) covariance




                    How's a raw type different from using <?> as a type parameter?



                    List<Object>, List<String>, etc are all List<?>, so it may be tempting to just say that they're just List instead. However, there is a major difference: since a List<E> defines only add(E), you can't add just any arbitrary object to a List<?>. On the other hand, since the raw type List does not have type safety, you can add just about anything to a List.



                    Consider the following variation of the previous snippet:



                    static void appendNewObject(List<?> list) {
                    list.add(new Object()); // compilation error!
                    }
                    //...

                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // this part is fine!


                    The compiler did a wonderful job of protecting you from potentially violating the type invariance of the List<?>! If you had declared the parameter as the raw type List list, then the code would compile, and you'd violate the type invariant of List<String> names.





                    A raw type is the erasure of that type



                    Back to JLS 4.8:




                    It is possible to use as a type the erasure of a parameterized type or the erasure of an array type whose element type is a parameterized type. Such a type is called a raw type.



                    [...]



                    The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.



                    The type of a constructor, instance method, or non-static field of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.




                    In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.



                    Take the following example:



                    class MyType<E> {
                    List<String> getNames() {
                    return Arrays.asList("John", "Mary");
                    }

                    public static void main(String args) {
                    MyType rawType = new MyType();
                    // unchecked warning!
                    // required: List<String> found: List
                    List<String> names = rawType.getNames();
                    // compilation error!
                    // incompatible types: Object cannot be converted to String
                    for (String str : rawType.getNames())
                    System.out.print(str);
                    }
                    }


                    When we use the raw MyType, getNames becomes erased as well, so that it returns a raw List!



                    JLS 4.6 continues to explain the following:




                    Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.



                    The return type of a method and the type parameters of a generic method or constructor also undergo erasure if the method or constructor's signature is erased.



                    The erasure of the signature of a generic method has no type parameters.




                    The following bug report contains some thoughts from Maurizio Cimadamore, a compiler dev, and Alex Buckley, one of the authors of the JLS, on why this sort of behavior ought to occur: https://bugs.openjdk.java.net/browse/JDK-6400189. (In short, it makes the specification simpler.)





                    If it's unsafe, why is it allowed to use a raw type?



                    Here's another quote from JLS 4.8:




                    The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




                    Effective Java 2nd Edition also has this to add:




                    Given that you shouldn't use raw types, why did the language designers allow them? To provide compatibility.



                    The Java platform was about to enter its second decade when generics were introduced, and there was an enormous amount of Java code in existence that did not use generics. It was deemed critical that all this code remains legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.




                    In summary, raw types should NEVER be used in new code. You should always use parameterized types.





                    Are there no exceptions?



                    Unfortunately, because Java generics are non-reified, there are two exceptions where raw types must be used in new code:




                    • Class literals, e.g. List.class, not List<String>.class


                    • instanceof operand, e.g. o instanceof Set, not o instanceof Set<String>


                    See also




                    • Why is Collection<String>.class Illegal?






                    share|improve this answer














                    What is a raw type?



                    The Java Language Specification defines a raw type as follows:



                    JLS 4.8 Raw Types




                    A raw type is defined to be one of:




                    • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.


                    • An array type whose element type is a raw type.


                    • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.





                    Here's an example to illustrate:



                    public class MyType<E> {
                    class Inner { }
                    static class Nested { }

                    public static void main(String args) {
                    MyType mt; // warning: MyType is a raw type
                    MyType.Inner inn; // warning: MyType.Inner is a raw type

                    MyType.Nested nest; // no warning: not parameterized type
                    MyType<Object> mt1; // no warning: type parameter given
                    MyType<?> mt2; // no warning: type parameter given (wildcard OK!)
                    }
                    }


                    Here, MyType<E> is a parameterized type (JLS 4.5). It is common to colloquially refer to this type as simply MyType for short, but technically the name is MyType<E>.



                    mt has a raw type (and generates a compilation warning) by the first bullet point in the above definition; inn also has a raw type by the third bullet point.



                    MyType.Nested is not a parameterized type, even though it's a member type of a parameterized type MyType<E>, because it's static.



                    mt1, and mt2 are both declared with actual type parameters, so they're not raw types.





                    What's so special about raw types?



                    Essentially, raw types behaves just like they were before generics were introduced. That is, the following is entirely legal at compile-time.



                    List names = new ArrayList(); // warning: raw type!
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // not a compilation error!


                    The above code runs just fine, but suppose you also have the following:



                    for (Object o : names) {
                    String name = (String) o;
                    System.out.println(name);
                    } // throws ClassCastException!
                    // java.lang.Boolean cannot be cast to java.lang.String


                    Now we run into trouble at run-time, because names contains something that isn't an instanceof String.



                    Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names. Even better, though is NOT to use a raw type and let the compiler do all the work for you, harnessing the power of Java generics.



                    List<String> names = new ArrayList<String>();
                    names.add("John");
                    names.add("Mary");
                    names.add(Boolean.FALSE); // compilation error!


                    Of course, if you DO want names to allow a Boolean, then you can declare it as List<Object> names, and the above code would compile.



                    See also




                    • Java Tutorials/Generics




                    How's a raw type different from using <Object> as type parameters?



                    The following is a quote from Effective Java 2nd Edition, Item 23: Don't use raw types in new code:




                    Just what is the difference between the raw type List and the parameterized type List<Object>? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List<String> to a parameter of type List, you can't pass it to a parameter of type List<Object>. There are subtyping rules for generics, and List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List<Object>.




                    To illustrate the point, consider the following method which takes a List<Object> and appends a new Object().



                    void appendNewObject(List<Object> list) {
                    list.add(new Object());
                    }


                    Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:



                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // compilation error!


                    If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.



                    See also




                    • What is the difference between <E extends Number> and <Number>?

                    • java generics (not) covariance




                    How's a raw type different from using <?> as a type parameter?



                    List<Object>, List<String>, etc are all List<?>, so it may be tempting to just say that they're just List instead. However, there is a major difference: since a List<E> defines only add(E), you can't add just any arbitrary object to a List<?>. On the other hand, since the raw type List does not have type safety, you can add just about anything to a List.



                    Consider the following variation of the previous snippet:



                    static void appendNewObject(List<?> list) {
                    list.add(new Object()); // compilation error!
                    }
                    //...

                    List<String> names = new ArrayList<String>();
                    appendNewObject(names); // this part is fine!


                    The compiler did a wonderful job of protecting you from potentially violating the type invariance of the List<?>! If you had declared the parameter as the raw type List list, then the code would compile, and you'd violate the type invariant of List<String> names.





                    A raw type is the erasure of that type



                    Back to JLS 4.8:




                    It is possible to use as a type the erasure of a parameterized type or the erasure of an array type whose element type is a parameterized type. Such a type is called a raw type.



                    [...]



                    The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.



                    The type of a constructor, instance method, or non-static field of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.




                    In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.



                    Take the following example:



                    class MyType<E> {
                    List<String> getNames() {
                    return Arrays.asList("John", "Mary");
                    }

                    public static void main(String args) {
                    MyType rawType = new MyType();
                    // unchecked warning!
                    // required: List<String> found: List
                    List<String> names = rawType.getNames();
                    // compilation error!
                    // incompatible types: Object cannot be converted to String
                    for (String str : rawType.getNames())
                    System.out.print(str);
                    }
                    }


                    When we use the raw MyType, getNames becomes erased as well, so that it returns a raw List!



                    JLS 4.6 continues to explain the following:




                    Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.



                    The return type of a method and the type parameters of a generic method or constructor also undergo erasure if the method or constructor's signature is erased.



                    The erasure of the signature of a generic method has no type parameters.




                    The following bug report contains some thoughts from Maurizio Cimadamore, a compiler dev, and Alex Buckley, one of the authors of the JLS, on why this sort of behavior ought to occur: https://bugs.openjdk.java.net/browse/JDK-6400189. (In short, it makes the specification simpler.)





                    If it's unsafe, why is it allowed to use a raw type?



                    Here's another quote from JLS 4.8:




                    The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




                    Effective Java 2nd Edition also has this to add:




                    Given that you shouldn't use raw types, why did the language designers allow them? To provide compatibility.



                    The Java platform was about to enter its second decade when generics were introduced, and there was an enormous amount of Java code in existence that did not use generics. It was deemed critical that all this code remains legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.




                    In summary, raw types should NEVER be used in new code. You should always use parameterized types.





                    Are there no exceptions?



                    Unfortunately, because Java generics are non-reified, there are two exceptions where raw types must be used in new code:




                    • Class literals, e.g. List.class, not List<String>.class


                    • instanceof operand, e.g. o instanceof Set, not o instanceof Set<String>


                    See also




                    • Why is Collection<String>.class Illegal?







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 29 at 23:46









                    Solomon Ucko

                    603719




                    603719










                    answered May 5 '10 at 4:50









                    polygenelubricants

                    280k101503591




                    280k101503591








                    • 13




                      What do you mean that, "Java generics are non-reified"?
                      – Carl G
                      Dec 15 '12 at 20:07






                    • 6




                      For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                      – Paul Bellora
                      May 20 '13 at 4:20






                    • 8




                      /me Slow claps at end of answer
                      – Dan Grahn
                      Jun 10 '14 at 18:56






                    • 6




                      "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                      – Erick G. Hagstrom
                      Jul 21 '15 at 18:24






                    • 2




                      @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                      – Radiodef
                      Apr 19 '16 at 14:09














                    • 13




                      What do you mean that, "Java generics are non-reified"?
                      – Carl G
                      Dec 15 '12 at 20:07






                    • 6




                      For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                      – Paul Bellora
                      May 20 '13 at 4:20






                    • 8




                      /me Slow claps at end of answer
                      – Dan Grahn
                      Jun 10 '14 at 18:56






                    • 6




                      "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                      – Erick G. Hagstrom
                      Jul 21 '15 at 18:24






                    • 2




                      @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                      – Radiodef
                      Apr 19 '16 at 14:09








                    13




                    13




                    What do you mean that, "Java generics are non-reified"?
                    – Carl G
                    Dec 15 '12 at 20:07




                    What do you mean that, "Java generics are non-reified"?
                    – Carl G
                    Dec 15 '12 at 20:07




                    6




                    6




                    For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                    – Paul Bellora
                    May 20 '13 at 4:20




                    For the second exception, the syntax o instanceof Set<?> is also permitted to avoid the raw type (though it's only superficial in this case).
                    – Paul Bellora
                    May 20 '13 at 4:20




                    8




                    8




                    /me Slow claps at end of answer
                    – Dan Grahn
                    Jun 10 '14 at 18:56




                    /me Slow claps at end of answer
                    – Dan Grahn
                    Jun 10 '14 at 18:56




                    6




                    6




                    "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                    – Erick G. Hagstrom
                    Jul 21 '15 at 18:24




                    "Non-reified" is another way of saying that they are erased. The compiler knows what the generic parameters are, but that information is not passed on to the generated bytecode. The JLS requires that class literals have no type parameters.
                    – Erick G. Hagstrom
                    Jul 21 '15 at 18:24




                    2




                    2




                    @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                    – Radiodef
                    Apr 19 '16 at 14:09




                    @OldCurmudgeon That's interesting. I mean officially it's neither, because a class literal defined as just TypeName.class, where TypeName is a plain identifier (jls). Speaking hypothetically, I guess it could really be either. Maybe as a clue, List<String>.class is the variant that the JLS specifically calls a compiler error, so if they ever add it to the language I'd expect that that is the one they use.
                    – Radiodef
                    Apr 19 '16 at 14:09












                    up vote
                    52
                    down vote














                    What are raw types in Java, and why do I often hear that they shouldn't be used in new code?




                    Raw-types are ancient history of the Java language. In the beginning there were Collections and they held Objects nothing more and nothing less. Every operation on Collections required casts from Object to the desired type.



                    List aList = new ArrayList();
                    String s = "Hello World!";
                    aList.add(s);
                    String c = (String)aList.get(0);


                    While this worked most of the time, errors did happen



                    List aNumberList = new ArrayList();
                    String one = "1";//Number one
                    aNumberList.add(one);
                    Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here


                    The old typeless collections could not enforce type-safety so the programmer had to remember what he stored within a collection.

                    Generics where invented to get around this limitation, the developer would declare the stored type once and the compiler would do it instead.



                    List<String> aNumberList = new ArrayList<String>();
                    aNumberList.add("one");
                    Integer iOne = aNumberList.get(0);//Compile time error
                    String sOne = aNumberList.get(0);//works fine


                    For Comparison:



                    // Old style collections now known as raw types
                    List aList = new ArrayList(); //Could contain anything
                    // New style collections with Generics
                    List<String> aList = new ArrayList<String>(); //Contains only Strings


                    More complex the Compareable interface:



                    //raw, not type save can compare with Other classes
                    class MyCompareAble implements CompareAble
                    {
                    int id;
                    public int compareTo(Object other)
                    {return this.id - ((MyCompareAble)other).id;}
                    }
                    //Generic
                    class MyCompareAble implements CompareAble<MyCompareAble>
                    {
                    int id;
                    public int compareTo(MyCompareAble other)
                    {return this.id - other.id;}
                    }


                    Note that it is impossible to implement the CompareAble interface with compareTo(MyCompareAble) with raw types.
                    Why you should not use them:




                    • Any Object stored in a Collection has to be cast before it can be used

                    • Using generics enables compile time checks

                    • Using raw types is the same as storing each value as Object


                    What the compiler does:
                    Generics are backward compatible, they use the same java classes as the raw types do. The magic happens mostly at compile time.



                    List<String> someStrings = new ArrayList<String>();
                    someStrings.add("one");
                    String one = someStrings.get(0);


                    Will be compiled as:



                    List someStrings = new ArrayList();
                    someStrings.add("one");
                    String one = (String)someStrings.get(0);


                    This is the same code you would write if you used the raw types directly. Thought I'm not sure what happens with the CompareAble interface, I guess that it creates two compareTo functions, one taking a MyCompareAble and the other taking an Object and passing it to the first after casting it.



                    What are the alternatives to raw types: Use generics






                    share|improve this answer



























                      up vote
                      52
                      down vote














                      What are raw types in Java, and why do I often hear that they shouldn't be used in new code?




                      Raw-types are ancient history of the Java language. In the beginning there were Collections and they held Objects nothing more and nothing less. Every operation on Collections required casts from Object to the desired type.



                      List aList = new ArrayList();
                      String s = "Hello World!";
                      aList.add(s);
                      String c = (String)aList.get(0);


                      While this worked most of the time, errors did happen



                      List aNumberList = new ArrayList();
                      String one = "1";//Number one
                      aNumberList.add(one);
                      Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here


                      The old typeless collections could not enforce type-safety so the programmer had to remember what he stored within a collection.

                      Generics where invented to get around this limitation, the developer would declare the stored type once and the compiler would do it instead.



                      List<String> aNumberList = new ArrayList<String>();
                      aNumberList.add("one");
                      Integer iOne = aNumberList.get(0);//Compile time error
                      String sOne = aNumberList.get(0);//works fine


                      For Comparison:



                      // Old style collections now known as raw types
                      List aList = new ArrayList(); //Could contain anything
                      // New style collections with Generics
                      List<String> aList = new ArrayList<String>(); //Contains only Strings


                      More complex the Compareable interface:



                      //raw, not type save can compare with Other classes
                      class MyCompareAble implements CompareAble
                      {
                      int id;
                      public int compareTo(Object other)
                      {return this.id - ((MyCompareAble)other).id;}
                      }
                      //Generic
                      class MyCompareAble implements CompareAble<MyCompareAble>
                      {
                      int id;
                      public int compareTo(MyCompareAble other)
                      {return this.id - other.id;}
                      }


                      Note that it is impossible to implement the CompareAble interface with compareTo(MyCompareAble) with raw types.
                      Why you should not use them:




                      • Any Object stored in a Collection has to be cast before it can be used

                      • Using generics enables compile time checks

                      • Using raw types is the same as storing each value as Object


                      What the compiler does:
                      Generics are backward compatible, they use the same java classes as the raw types do. The magic happens mostly at compile time.



                      List<String> someStrings = new ArrayList<String>();
                      someStrings.add("one");
                      String one = someStrings.get(0);


                      Will be compiled as:



                      List someStrings = new ArrayList();
                      someStrings.add("one");
                      String one = (String)someStrings.get(0);


                      This is the same code you would write if you used the raw types directly. Thought I'm not sure what happens with the CompareAble interface, I guess that it creates two compareTo functions, one taking a MyCompareAble and the other taking an Object and passing it to the first after casting it.



                      What are the alternatives to raw types: Use generics






                      share|improve this answer

























                        up vote
                        52
                        down vote










                        up vote
                        52
                        down vote










                        What are raw types in Java, and why do I often hear that they shouldn't be used in new code?




                        Raw-types are ancient history of the Java language. In the beginning there were Collections and they held Objects nothing more and nothing less. Every operation on Collections required casts from Object to the desired type.



                        List aList = new ArrayList();
                        String s = "Hello World!";
                        aList.add(s);
                        String c = (String)aList.get(0);


                        While this worked most of the time, errors did happen



                        List aNumberList = new ArrayList();
                        String one = "1";//Number one
                        aNumberList.add(one);
                        Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here


                        The old typeless collections could not enforce type-safety so the programmer had to remember what he stored within a collection.

                        Generics where invented to get around this limitation, the developer would declare the stored type once and the compiler would do it instead.



                        List<String> aNumberList = new ArrayList<String>();
                        aNumberList.add("one");
                        Integer iOne = aNumberList.get(0);//Compile time error
                        String sOne = aNumberList.get(0);//works fine


                        For Comparison:



                        // Old style collections now known as raw types
                        List aList = new ArrayList(); //Could contain anything
                        // New style collections with Generics
                        List<String> aList = new ArrayList<String>(); //Contains only Strings


                        More complex the Compareable interface:



                        //raw, not type save can compare with Other classes
                        class MyCompareAble implements CompareAble
                        {
                        int id;
                        public int compareTo(Object other)
                        {return this.id - ((MyCompareAble)other).id;}
                        }
                        //Generic
                        class MyCompareAble implements CompareAble<MyCompareAble>
                        {
                        int id;
                        public int compareTo(MyCompareAble other)
                        {return this.id - other.id;}
                        }


                        Note that it is impossible to implement the CompareAble interface with compareTo(MyCompareAble) with raw types.
                        Why you should not use them:




                        • Any Object stored in a Collection has to be cast before it can be used

                        • Using generics enables compile time checks

                        • Using raw types is the same as storing each value as Object


                        What the compiler does:
                        Generics are backward compatible, they use the same java classes as the raw types do. The magic happens mostly at compile time.



                        List<String> someStrings = new ArrayList<String>();
                        someStrings.add("one");
                        String one = someStrings.get(0);


                        Will be compiled as:



                        List someStrings = new ArrayList();
                        someStrings.add("one");
                        String one = (String)someStrings.get(0);


                        This is the same code you would write if you used the raw types directly. Thought I'm not sure what happens with the CompareAble interface, I guess that it creates two compareTo functions, one taking a MyCompareAble and the other taking an Object and passing it to the first after casting it.



                        What are the alternatives to raw types: Use generics






                        share|improve this answer















                        What are raw types in Java, and why do I often hear that they shouldn't be used in new code?




                        Raw-types are ancient history of the Java language. In the beginning there were Collections and they held Objects nothing more and nothing less. Every operation on Collections required casts from Object to the desired type.



                        List aList = new ArrayList();
                        String s = "Hello World!";
                        aList.add(s);
                        String c = (String)aList.get(0);


                        While this worked most of the time, errors did happen



                        List aNumberList = new ArrayList();
                        String one = "1";//Number one
                        aNumberList.add(one);
                        Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here


                        The old typeless collections could not enforce type-safety so the programmer had to remember what he stored within a collection.

                        Generics where invented to get around this limitation, the developer would declare the stored type once and the compiler would do it instead.



                        List<String> aNumberList = new ArrayList<String>();
                        aNumberList.add("one");
                        Integer iOne = aNumberList.get(0);//Compile time error
                        String sOne = aNumberList.get(0);//works fine


                        For Comparison:



                        // Old style collections now known as raw types
                        List aList = new ArrayList(); //Could contain anything
                        // New style collections with Generics
                        List<String> aList = new ArrayList<String>(); //Contains only Strings


                        More complex the Compareable interface:



                        //raw, not type save can compare with Other classes
                        class MyCompareAble implements CompareAble
                        {
                        int id;
                        public int compareTo(Object other)
                        {return this.id - ((MyCompareAble)other).id;}
                        }
                        //Generic
                        class MyCompareAble implements CompareAble<MyCompareAble>
                        {
                        int id;
                        public int compareTo(MyCompareAble other)
                        {return this.id - other.id;}
                        }


                        Note that it is impossible to implement the CompareAble interface with compareTo(MyCompareAble) with raw types.
                        Why you should not use them:




                        • Any Object stored in a Collection has to be cast before it can be used

                        • Using generics enables compile time checks

                        • Using raw types is the same as storing each value as Object


                        What the compiler does:
                        Generics are backward compatible, they use the same java classes as the raw types do. The magic happens mostly at compile time.



                        List<String> someStrings = new ArrayList<String>();
                        someStrings.add("one");
                        String one = someStrings.get(0);


                        Will be compiled as:



                        List someStrings = new ArrayList();
                        someStrings.add("one");
                        String one = (String)someStrings.get(0);


                        This is the same code you would write if you used the raw types directly. Thought I'm not sure what happens with the CompareAble interface, I guess that it creates two compareTo functions, one taking a MyCompareAble and the other taking an Object and passing it to the first after casting it.



                        What are the alternatives to raw types: Use generics







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Nov 21 '15 at 0:48









                        jiaweizhang

                        6811724




                        6811724










                        answered May 5 '10 at 21:50









                        josefx

                        13.2k52755




                        13.2k52755






















                            up vote
                            22
                            down vote













                            A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                            public class Box<T> {
                            public void set(T t) { /* ... */ }
                            // ...
                            }


                            To create a parameterized type of Box<T>, you supply an actual type argument for the formal type parameter T:



                            Box<Integer> intBox = new Box<>();


                            If the actual type argument is omitted, you create a raw type of Box<T>:



                            Box rawBox = new Box();


                            Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type.



                            Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:



                            Box<String> stringBox = new Box<>();
                            Box rawBox = stringBox; // OK


                            But if you assign a raw type to a parameterized type, you get a warning:



                            Box rawBox = new Box();           // rawBox is a raw type of Box<T>
                            Box<Integer> intBox = rawBox; // warning: unchecked conversion


                            You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:



                            Box<String> stringBox = new Box<>();
                            Box rawBox = stringBox;
                            rawBox.set(8); // warning: unchecked invocation to set(T)


                            The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.



                            The Type Erasure section has more information on how the Java compiler uses raw types.



                            Unchecked Error Messages



                            As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:




                            Note: Example.java uses unchecked or unsafe operations.



                            Note: Recompile with -Xlint:unchecked for details.




                            This can happen when using an older API that operates on raw types, as shown in the following example:



                            public class WarningDemo {
                            public static void main(String args){
                            Box<Integer> bi;
                            bi = createBox();
                            }

                            static Box createBox(){
                            return new Box();
                            }
                            }


                            The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.



                            Recompiling the previous example with -Xlint:unchecked reveals the following additional information:



                            WarningDemo.java:4: warning: [unchecked] unchecked conversion
                            found : Box
                            required: Box<java.lang.Integer>
                            bi = createBox();
                            ^
                            1 warning


                            To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.



                            Original source: Java Tutorials






                            share|improve this answer



























                              up vote
                              22
                              down vote













                              A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                              public class Box<T> {
                              public void set(T t) { /* ... */ }
                              // ...
                              }


                              To create a parameterized type of Box<T>, you supply an actual type argument for the formal type parameter T:



                              Box<Integer> intBox = new Box<>();


                              If the actual type argument is omitted, you create a raw type of Box<T>:



                              Box rawBox = new Box();


                              Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type.



                              Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:



                              Box<String> stringBox = new Box<>();
                              Box rawBox = stringBox; // OK


                              But if you assign a raw type to a parameterized type, you get a warning:



                              Box rawBox = new Box();           // rawBox is a raw type of Box<T>
                              Box<Integer> intBox = rawBox; // warning: unchecked conversion


                              You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:



                              Box<String> stringBox = new Box<>();
                              Box rawBox = stringBox;
                              rawBox.set(8); // warning: unchecked invocation to set(T)


                              The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.



                              The Type Erasure section has more information on how the Java compiler uses raw types.



                              Unchecked Error Messages



                              As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:




                              Note: Example.java uses unchecked or unsafe operations.



                              Note: Recompile with -Xlint:unchecked for details.




                              This can happen when using an older API that operates on raw types, as shown in the following example:



                              public class WarningDemo {
                              public static void main(String args){
                              Box<Integer> bi;
                              bi = createBox();
                              }

                              static Box createBox(){
                              return new Box();
                              }
                              }


                              The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.



                              Recompiling the previous example with -Xlint:unchecked reveals the following additional information:



                              WarningDemo.java:4: warning: [unchecked] unchecked conversion
                              found : Box
                              required: Box<java.lang.Integer>
                              bi = createBox();
                              ^
                              1 warning


                              To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.



                              Original source: Java Tutorials






                              share|improve this answer

























                                up vote
                                22
                                down vote










                                up vote
                                22
                                down vote









                                A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                public class Box<T> {
                                public void set(T t) { /* ... */ }
                                // ...
                                }


                                To create a parameterized type of Box<T>, you supply an actual type argument for the formal type parameter T:



                                Box<Integer> intBox = new Box<>();


                                If the actual type argument is omitted, you create a raw type of Box<T>:



                                Box rawBox = new Box();


                                Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type.



                                Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:



                                Box<String> stringBox = new Box<>();
                                Box rawBox = stringBox; // OK


                                But if you assign a raw type to a parameterized type, you get a warning:



                                Box rawBox = new Box();           // rawBox is a raw type of Box<T>
                                Box<Integer> intBox = rawBox; // warning: unchecked conversion


                                You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:



                                Box<String> stringBox = new Box<>();
                                Box rawBox = stringBox;
                                rawBox.set(8); // warning: unchecked invocation to set(T)


                                The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.



                                The Type Erasure section has more information on how the Java compiler uses raw types.



                                Unchecked Error Messages



                                As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:




                                Note: Example.java uses unchecked or unsafe operations.



                                Note: Recompile with -Xlint:unchecked for details.




                                This can happen when using an older API that operates on raw types, as shown in the following example:



                                public class WarningDemo {
                                public static void main(String args){
                                Box<Integer> bi;
                                bi = createBox();
                                }

                                static Box createBox(){
                                return new Box();
                                }
                                }


                                The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.



                                Recompiling the previous example with -Xlint:unchecked reveals the following additional information:



                                WarningDemo.java:4: warning: [unchecked] unchecked conversion
                                found : Box
                                required: Box<java.lang.Integer>
                                bi = createBox();
                                ^
                                1 warning


                                To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.



                                Original source: Java Tutorials






                                share|improve this answer














                                A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                public class Box<T> {
                                public void set(T t) { /* ... */ }
                                // ...
                                }


                                To create a parameterized type of Box<T>, you supply an actual type argument for the formal type parameter T:



                                Box<Integer> intBox = new Box<>();


                                If the actual type argument is omitted, you create a raw type of Box<T>:



                                Box rawBox = new Box();


                                Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type.



                                Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:



                                Box<String> stringBox = new Box<>();
                                Box rawBox = stringBox; // OK


                                But if you assign a raw type to a parameterized type, you get a warning:



                                Box rawBox = new Box();           // rawBox is a raw type of Box<T>
                                Box<Integer> intBox = rawBox; // warning: unchecked conversion


                                You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:



                                Box<String> stringBox = new Box<>();
                                Box rawBox = stringBox;
                                rawBox.set(8); // warning: unchecked invocation to set(T)


                                The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.



                                The Type Erasure section has more information on how the Java compiler uses raw types.



                                Unchecked Error Messages



                                As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:




                                Note: Example.java uses unchecked or unsafe operations.



                                Note: Recompile with -Xlint:unchecked for details.




                                This can happen when using an older API that operates on raw types, as shown in the following example:



                                public class WarningDemo {
                                public static void main(String args){
                                Box<Integer> bi;
                                bi = createBox();
                                }

                                static Box createBox(){
                                return new Box();
                                }
                                }


                                The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with -Xlint:unchecked.



                                Recompiling the previous example with -Xlint:unchecked reveals the following additional information:



                                WarningDemo.java:4: warning: [unchecked] unchecked conversion
                                found : Box
                                required: Box<java.lang.Integer>
                                bi = createBox();
                                ^
                                1 warning


                                To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings("unchecked") annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.



                                Original source: Java Tutorials







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Aug 11 '13 at 0:29









                                Paul Bellora

                                45.2k15111161




                                45.2k15111161










                                answered Aug 10 '13 at 23:58









                                Adelin

                                7,0101575121




                                7,0101575121






















                                    up vote
                                    17
                                    down vote













                                     private static List<String> list = new ArrayList<String>();


                                    You should specify the type-parameter.



                                    The warning advises that types that are defined to support generics should be parameterized, rather than using their raw form.



                                    List is defined to support generics: public class List<E>. This allows many type-safe operations, that are checked compile-time.






                                    share|improve this answer

















                                    • 2




                                      Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                      – Ian Campbell
                                      Oct 10 '14 at 14:03















                                    up vote
                                    17
                                    down vote













                                     private static List<String> list = new ArrayList<String>();


                                    You should specify the type-parameter.



                                    The warning advises that types that are defined to support generics should be parameterized, rather than using their raw form.



                                    List is defined to support generics: public class List<E>. This allows many type-safe operations, that are checked compile-time.






                                    share|improve this answer

















                                    • 2




                                      Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                      – Ian Campbell
                                      Oct 10 '14 at 14:03













                                    up vote
                                    17
                                    down vote










                                    up vote
                                    17
                                    down vote









                                     private static List<String> list = new ArrayList<String>();


                                    You should specify the type-parameter.



                                    The warning advises that types that are defined to support generics should be parameterized, rather than using their raw form.



                                    List is defined to support generics: public class List<E>. This allows many type-safe operations, that are checked compile-time.






                                    share|improve this answer












                                     private static List<String> list = new ArrayList<String>();


                                    You should specify the type-parameter.



                                    The warning advises that types that are defined to support generics should be parameterized, rather than using their raw form.



                                    List is defined to support generics: public class List<E>. This allows many type-safe operations, that are checked compile-time.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Jun 16 '10 at 7:44









                                    Bozho

                                    481k1079421056




                                    481k1079421056








                                    • 2




                                      Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                      – Ian Campbell
                                      Oct 10 '14 at 14:03














                                    • 2




                                      Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                      – Ian Campbell
                                      Oct 10 '14 at 14:03








                                    2




                                    2




                                    Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                    – Ian Campbell
                                    Oct 10 '14 at 14:03




                                    Now replaced by diamond inference in Java 7 -- private static List<String> list = new ArrayList<>();
                                    – Ian Campbell
                                    Oct 10 '14 at 14:03










                                    up vote
                                    14
                                    down vote













                                    A "raw" type in Java is a class which is non-generic and deals with "raw" Objects, rather than type-safe generic type parameters.



                                    For example, before Java generics was available, you would use a collection class like this:



                                    LinkedList list = new LinkedList();
                                    list.add(new MyObject());
                                    MyObject myObject = (MyObject)list.get(0);


                                    When you add your object to the list, it doesn't care what type of object it is, and when you get it from the list, you have to explicitly cast it to the type you are expecting.



                                    Using generics, you remove the "unknown" factor, because you must explicitly specify which type of objects can go in the list:



                                    LinkedList<MyObject> list = new LinkedList<MyObject>();
                                    list.add(new MyObject());
                                    MyObject myObject = list.get(0);


                                    Notice that with generics you don't have to cast the object coming from the get call, the collection is pre-defined to only work with MyObject. This very fact is the main driving factor for generics. It changes a source of runtime errors into something that can be checked at compile time.






                                    share|improve this answer

















                                    • 3




                                      More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                      – John Flatness
                                      May 5 '10 at 3:10










                                    • @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                      – polygenelubricants
                                      May 5 '10 at 5:08















                                    up vote
                                    14
                                    down vote













                                    A "raw" type in Java is a class which is non-generic and deals with "raw" Objects, rather than type-safe generic type parameters.



                                    For example, before Java generics was available, you would use a collection class like this:



                                    LinkedList list = new LinkedList();
                                    list.add(new MyObject());
                                    MyObject myObject = (MyObject)list.get(0);


                                    When you add your object to the list, it doesn't care what type of object it is, and when you get it from the list, you have to explicitly cast it to the type you are expecting.



                                    Using generics, you remove the "unknown" factor, because you must explicitly specify which type of objects can go in the list:



                                    LinkedList<MyObject> list = new LinkedList<MyObject>();
                                    list.add(new MyObject());
                                    MyObject myObject = list.get(0);


                                    Notice that with generics you don't have to cast the object coming from the get call, the collection is pre-defined to only work with MyObject. This very fact is the main driving factor for generics. It changes a source of runtime errors into something that can be checked at compile time.






                                    share|improve this answer

















                                    • 3




                                      More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                      – John Flatness
                                      May 5 '10 at 3:10










                                    • @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                      – polygenelubricants
                                      May 5 '10 at 5:08













                                    up vote
                                    14
                                    down vote










                                    up vote
                                    14
                                    down vote









                                    A "raw" type in Java is a class which is non-generic and deals with "raw" Objects, rather than type-safe generic type parameters.



                                    For example, before Java generics was available, you would use a collection class like this:



                                    LinkedList list = new LinkedList();
                                    list.add(new MyObject());
                                    MyObject myObject = (MyObject)list.get(0);


                                    When you add your object to the list, it doesn't care what type of object it is, and when you get it from the list, you have to explicitly cast it to the type you are expecting.



                                    Using generics, you remove the "unknown" factor, because you must explicitly specify which type of objects can go in the list:



                                    LinkedList<MyObject> list = new LinkedList<MyObject>();
                                    list.add(new MyObject());
                                    MyObject myObject = list.get(0);


                                    Notice that with generics you don't have to cast the object coming from the get call, the collection is pre-defined to only work with MyObject. This very fact is the main driving factor for generics. It changes a source of runtime errors into something that can be checked at compile time.






                                    share|improve this answer












                                    A "raw" type in Java is a class which is non-generic and deals with "raw" Objects, rather than type-safe generic type parameters.



                                    For example, before Java generics was available, you would use a collection class like this:



                                    LinkedList list = new LinkedList();
                                    list.add(new MyObject());
                                    MyObject myObject = (MyObject)list.get(0);


                                    When you add your object to the list, it doesn't care what type of object it is, and when you get it from the list, you have to explicitly cast it to the type you are expecting.



                                    Using generics, you remove the "unknown" factor, because you must explicitly specify which type of objects can go in the list:



                                    LinkedList<MyObject> list = new LinkedList<MyObject>();
                                    list.add(new MyObject());
                                    MyObject myObject = list.get(0);


                                    Notice that with generics you don't have to cast the object coming from the get call, the collection is pre-defined to only work with MyObject. This very fact is the main driving factor for generics. It changes a source of runtime errors into something that can be checked at compile time.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered May 5 '10 at 2:58









                                    Andy White

                                    57.6k46156198




                                    57.6k46156198








                                    • 3




                                      More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                      – John Flatness
                                      May 5 '10 at 3:10










                                    • @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                      – polygenelubricants
                                      May 5 '10 at 5:08














                                    • 3




                                      More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                      – John Flatness
                                      May 5 '10 at 3:10










                                    • @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                      – polygenelubricants
                                      May 5 '10 at 5:08








                                    3




                                    3




                                    More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                    – John Flatness
                                    May 5 '10 at 3:10




                                    More specifically, a raw type is what you get when you simply omit the type parameters for a generic type. Raw types were really only ever a backwards-compatibility feature, and are potentially subject to removal. You can get similar behavior using ? wildcard parameters.
                                    – John Flatness
                                    May 5 '10 at 3:10












                                    @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                    – polygenelubricants
                                    May 5 '10 at 5:08




                                    @zerocrates: similar but different! Using ? still offers type safety. I covered it in my answer.
                                    – polygenelubricants
                                    May 5 '10 at 5:08










                                    up vote
                                    10
                                    down vote













                                    What is a raw type and why do I often hear that they shouldn't be used in new code?



                                    A "raw type" is the use of a generic class without specifying a type argument(s) for its parameterized type(s), e.g. using List instead of List<String>. When generics were introduced into Java, several classes were updated to use generics. Using these class as a "raw type" (without specifying a type argument) allowed legacy code to still compile.



                                    "Raw types" are used for backwards compatibility. Their use in new code is not recommended because using the generic class with a type argument allows for stronger typing, which in turn may improve code understandability and lead to catching potential problems earlier.



                                    What is the alternative if we can't use raw types, and how is it better?



                                    The preferred alternative is to use generic classes as intended - with a suitable type argument (e.g. List<String>). This allows the programmer to specify types more specifically, conveys more meaning to future maintainers about the intended use of a variable or data structure, and it allows compiler to enforce better type-safety. These advantages together may improve code quality and help prevent the introduction of some coding errors.



                                    For example, for a method where the programmer wants to ensure a List variable called 'names' contains only Strings:



                                    List<String> names = new ArrayList<String>();
                                    names.add("John"); // OK
                                    names.add(new Integer(1)); // compile error





                                    share|improve this answer

















                                    • 1




                                      Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                      – Bert F
                                      May 5 '10 at 4:38






                                    • 1




                                      yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                      – polygenelubricants
                                      May 5 '10 at 5:02








                                    • 1




                                      @polygenelubricants I noticed - we hit some of the same questions :-)
                                      – Bert F
                                      May 5 '10 at 5:17






                                    • 1




                                      this answer is much better than the accepted one - concise and simple
                                      – ha9u63ar
                                      Aug 2 '16 at 11:47






                                    • 1




                                      @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                      – displayName
                                      Aug 7 '17 at 15:02















                                    up vote
                                    10
                                    down vote













                                    What is a raw type and why do I often hear that they shouldn't be used in new code?



                                    A "raw type" is the use of a generic class without specifying a type argument(s) for its parameterized type(s), e.g. using List instead of List<String>. When generics were introduced into Java, several classes were updated to use generics. Using these class as a "raw type" (without specifying a type argument) allowed legacy code to still compile.



                                    "Raw types" are used for backwards compatibility. Their use in new code is not recommended because using the generic class with a type argument allows for stronger typing, which in turn may improve code understandability and lead to catching potential problems earlier.



                                    What is the alternative if we can't use raw types, and how is it better?



                                    The preferred alternative is to use generic classes as intended - with a suitable type argument (e.g. List<String>). This allows the programmer to specify types more specifically, conveys more meaning to future maintainers about the intended use of a variable or data structure, and it allows compiler to enforce better type-safety. These advantages together may improve code quality and help prevent the introduction of some coding errors.



                                    For example, for a method where the programmer wants to ensure a List variable called 'names' contains only Strings:



                                    List<String> names = new ArrayList<String>();
                                    names.add("John"); // OK
                                    names.add(new Integer(1)); // compile error





                                    share|improve this answer

















                                    • 1




                                      Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                      – Bert F
                                      May 5 '10 at 4:38






                                    • 1




                                      yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                      – polygenelubricants
                                      May 5 '10 at 5:02








                                    • 1




                                      @polygenelubricants I noticed - we hit some of the same questions :-)
                                      – Bert F
                                      May 5 '10 at 5:17






                                    • 1




                                      this answer is much better than the accepted one - concise and simple
                                      – ha9u63ar
                                      Aug 2 '16 at 11:47






                                    • 1




                                      @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                      – displayName
                                      Aug 7 '17 at 15:02













                                    up vote
                                    10
                                    down vote










                                    up vote
                                    10
                                    down vote









                                    What is a raw type and why do I often hear that they shouldn't be used in new code?



                                    A "raw type" is the use of a generic class without specifying a type argument(s) for its parameterized type(s), e.g. using List instead of List<String>. When generics were introduced into Java, several classes were updated to use generics. Using these class as a "raw type" (without specifying a type argument) allowed legacy code to still compile.



                                    "Raw types" are used for backwards compatibility. Their use in new code is not recommended because using the generic class with a type argument allows for stronger typing, which in turn may improve code understandability and lead to catching potential problems earlier.



                                    What is the alternative if we can't use raw types, and how is it better?



                                    The preferred alternative is to use generic classes as intended - with a suitable type argument (e.g. List<String>). This allows the programmer to specify types more specifically, conveys more meaning to future maintainers about the intended use of a variable or data structure, and it allows compiler to enforce better type-safety. These advantages together may improve code quality and help prevent the introduction of some coding errors.



                                    For example, for a method where the programmer wants to ensure a List variable called 'names' contains only Strings:



                                    List<String> names = new ArrayList<String>();
                                    names.add("John"); // OK
                                    names.add(new Integer(1)); // compile error





                                    share|improve this answer












                                    What is a raw type and why do I often hear that they shouldn't be used in new code?



                                    A "raw type" is the use of a generic class without specifying a type argument(s) for its parameterized type(s), e.g. using List instead of List<String>. When generics were introduced into Java, several classes were updated to use generics. Using these class as a "raw type" (without specifying a type argument) allowed legacy code to still compile.



                                    "Raw types" are used for backwards compatibility. Their use in new code is not recommended because using the generic class with a type argument allows for stronger typing, which in turn may improve code understandability and lead to catching potential problems earlier.



                                    What is the alternative if we can't use raw types, and how is it better?



                                    The preferred alternative is to use generic classes as intended - with a suitable type argument (e.g. List<String>). This allows the programmer to specify types more specifically, conveys more meaning to future maintainers about the intended use of a variable or data structure, and it allows compiler to enforce better type-safety. These advantages together may improve code quality and help prevent the introduction of some coding errors.



                                    For example, for a method where the programmer wants to ensure a List variable called 'names' contains only Strings:



                                    List<String> names = new ArrayList<String>();
                                    names.add("John"); // OK
                                    names.add(new Integer(1)); // compile error






                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered May 5 '10 at 4:31









                                    Bert F

                                    62.9k1088118




                                    62.9k1088118








                                    • 1




                                      Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                      – Bert F
                                      May 5 '10 at 4:38






                                    • 1




                                      yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                      – polygenelubricants
                                      May 5 '10 at 5:02








                                    • 1




                                      @polygenelubricants I noticed - we hit some of the same questions :-)
                                      – Bert F
                                      May 5 '10 at 5:17






                                    • 1




                                      this answer is much better than the accepted one - concise and simple
                                      – ha9u63ar
                                      Aug 2 '16 at 11:47






                                    • 1




                                      @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                      – displayName
                                      Aug 7 '17 at 15:02














                                    • 1




                                      Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                      – Bert F
                                      May 5 '10 at 4:38






                                    • 1




                                      yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                      – polygenelubricants
                                      May 5 '10 at 5:02








                                    • 1




                                      @polygenelubricants I noticed - we hit some of the same questions :-)
                                      – Bert F
                                      May 5 '10 at 5:17






                                    • 1




                                      this answer is much better than the accepted one - concise and simple
                                      – ha9u63ar
                                      Aug 2 '16 at 11:47






                                    • 1




                                      @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                      – displayName
                                      Aug 7 '17 at 15:02








                                    1




                                    1




                                    Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                    – Bert F
                                    May 5 '10 at 4:38




                                    Ah, so tempted to copy polygenelubricants's "raw type" references from stackoverflow.com/questions/2770111/… into my own answer, but I suppose I'll leave them for use in his/her own answer.
                                    – Bert F
                                    May 5 '10 at 4:38




                                    1




                                    1




                                    yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                    – polygenelubricants
                                    May 5 '10 at 5:02






                                    yes, I've been essentially copying-and-pasting that segment everywhere people use raw types on stackoverflow, and finally decided to just have one question to refer to from now on. I hope it's a good contribution for the community.
                                    – polygenelubricants
                                    May 5 '10 at 5:02






                                    1




                                    1




                                    @polygenelubricants I noticed - we hit some of the same questions :-)
                                    – Bert F
                                    May 5 '10 at 5:17




                                    @polygenelubricants I noticed - we hit some of the same questions :-)
                                    – Bert F
                                    May 5 '10 at 5:17




                                    1




                                    1




                                    this answer is much better than the accepted one - concise and simple
                                    – ha9u63ar
                                    Aug 2 '16 at 11:47




                                    this answer is much better than the accepted one - concise and simple
                                    – ha9u63ar
                                    Aug 2 '16 at 11:47




                                    1




                                    1




                                    @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                    – displayName
                                    Aug 7 '17 at 15:02




                                    @ha9u63ar: Indeed. In general concise and simple answers are at least as good as the long and accepted ones.
                                    – displayName
                                    Aug 7 '17 at 15:02










                                    up vote
                                    10
                                    down vote













                                    The compiler wants you to write this:



                                    private static List<String> list = new ArrayList<String>();


                                    because otherwise, you could add any type you like into list, making the instantiation as new ArrayList<String>() pointless. Java generics are a compile-time feature only, so an object created with new ArrayList<String>() will happily accept Integer or JFrame elements if assigned to a reference of the "raw type" List - the object itself knows nothing about what types it's supposed to contain, only the compiler does.






                                    share|improve this answer

























                                      up vote
                                      10
                                      down vote













                                      The compiler wants you to write this:



                                      private static List<String> list = new ArrayList<String>();


                                      because otherwise, you could add any type you like into list, making the instantiation as new ArrayList<String>() pointless. Java generics are a compile-time feature only, so an object created with new ArrayList<String>() will happily accept Integer or JFrame elements if assigned to a reference of the "raw type" List - the object itself knows nothing about what types it's supposed to contain, only the compiler does.






                                      share|improve this answer























                                        up vote
                                        10
                                        down vote










                                        up vote
                                        10
                                        down vote









                                        The compiler wants you to write this:



                                        private static List<String> list = new ArrayList<String>();


                                        because otherwise, you could add any type you like into list, making the instantiation as new ArrayList<String>() pointless. Java generics are a compile-time feature only, so an object created with new ArrayList<String>() will happily accept Integer or JFrame elements if assigned to a reference of the "raw type" List - the object itself knows nothing about what types it's supposed to contain, only the compiler does.






                                        share|improve this answer












                                        The compiler wants you to write this:



                                        private static List<String> list = new ArrayList<String>();


                                        because otherwise, you could add any type you like into list, making the instantiation as new ArrayList<String>() pointless. Java generics are a compile-time feature only, so an object created with new ArrayList<String>() will happily accept Integer or JFrame elements if assigned to a reference of the "raw type" List - the object itself knows nothing about what types it's supposed to contain, only the compiler does.







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Jun 16 '10 at 7:53









                                        Michael Borgwardt

                                        293k63426662




                                        293k63426662






















                                            up vote
                                            9
                                            down vote













                                            Here I am Considering multiple cases through which you can clearify the concept



                                            1. ArrayList<String> arr = new ArrayList<String>();
                                            2. ArrayList<String> arr = new ArrayList();
                                            3. ArrayList arr = new ArrayList<String>();


                                            Case 1



                                            ArrayList<String> arr it is a ArrayList reference variable with type String which reference to a ArralyList Object of Type String. It means it can hold only String type Object.



                                            It is a Strict to String not a Raw Type so, It will never raise an warning .



                                                arr.add("hello");// alone statement will compile successfully and no warning.

                                            arr.add(23); //prone to compile time error.
                                            //error: no suitable method found for add(int)


                                            Case 2



                                            In this case ArrayList<String> arr is a strict type but your Object new ArrayList(); is a raw type.



                                                arr.add("hello"); //alone this compile but raise the warning.
                                            arr.add(23); //again prone to compile time error.
                                            //error: no suitable method found for add(int)


                                            here arr is a Strict type. So, It will raise compile time error when adding a integer.




                                            Warning :- A Raw Type Object is referenced to a Strict type Referenced Variable of ArrayList.




                                            Case 3



                                            In this case ArrayList arr is a raw type but your Object new ArrayList<String>(); is a Strict type.



                                                arr.add("hello");  
                                            arr.add(23); //compiles fine but raise the warning.


                                            It will add any type of Object into it because arr is a Raw Type.




                                            Warning :- A Strict Type Object is referenced to a raw type referenced Variable.







                                            share|improve this answer



























                                              up vote
                                              9
                                              down vote













                                              Here I am Considering multiple cases through which you can clearify the concept



                                              1. ArrayList<String> arr = new ArrayList<String>();
                                              2. ArrayList<String> arr = new ArrayList();
                                              3. ArrayList arr = new ArrayList<String>();


                                              Case 1



                                              ArrayList<String> arr it is a ArrayList reference variable with type String which reference to a ArralyList Object of Type String. It means it can hold only String type Object.



                                              It is a Strict to String not a Raw Type so, It will never raise an warning .



                                                  arr.add("hello");// alone statement will compile successfully and no warning.

                                              arr.add(23); //prone to compile time error.
                                              //error: no suitable method found for add(int)


                                              Case 2



                                              In this case ArrayList<String> arr is a strict type but your Object new ArrayList(); is a raw type.



                                                  arr.add("hello"); //alone this compile but raise the warning.
                                              arr.add(23); //again prone to compile time error.
                                              //error: no suitable method found for add(int)


                                              here arr is a Strict type. So, It will raise compile time error when adding a integer.




                                              Warning :- A Raw Type Object is referenced to a Strict type Referenced Variable of ArrayList.




                                              Case 3



                                              In this case ArrayList arr is a raw type but your Object new ArrayList<String>(); is a Strict type.



                                                  arr.add("hello");  
                                              arr.add(23); //compiles fine but raise the warning.


                                              It will add any type of Object into it because arr is a Raw Type.




                                              Warning :- A Strict Type Object is referenced to a raw type referenced Variable.







                                              share|improve this answer

























                                                up vote
                                                9
                                                down vote










                                                up vote
                                                9
                                                down vote









                                                Here I am Considering multiple cases through which you can clearify the concept



                                                1. ArrayList<String> arr = new ArrayList<String>();
                                                2. ArrayList<String> arr = new ArrayList();
                                                3. ArrayList arr = new ArrayList<String>();


                                                Case 1



                                                ArrayList<String> arr it is a ArrayList reference variable with type String which reference to a ArralyList Object of Type String. It means it can hold only String type Object.



                                                It is a Strict to String not a Raw Type so, It will never raise an warning .



                                                    arr.add("hello");// alone statement will compile successfully and no warning.

                                                arr.add(23); //prone to compile time error.
                                                //error: no suitable method found for add(int)


                                                Case 2



                                                In this case ArrayList<String> arr is a strict type but your Object new ArrayList(); is a raw type.



                                                    arr.add("hello"); //alone this compile but raise the warning.
                                                arr.add(23); //again prone to compile time error.
                                                //error: no suitable method found for add(int)


                                                here arr is a Strict type. So, It will raise compile time error when adding a integer.




                                                Warning :- A Raw Type Object is referenced to a Strict type Referenced Variable of ArrayList.




                                                Case 3



                                                In this case ArrayList arr is a raw type but your Object new ArrayList<String>(); is a Strict type.



                                                    arr.add("hello");  
                                                arr.add(23); //compiles fine but raise the warning.


                                                It will add any type of Object into it because arr is a Raw Type.




                                                Warning :- A Strict Type Object is referenced to a raw type referenced Variable.







                                                share|improve this answer














                                                Here I am Considering multiple cases through which you can clearify the concept



                                                1. ArrayList<String> arr = new ArrayList<String>();
                                                2. ArrayList<String> arr = new ArrayList();
                                                3. ArrayList arr = new ArrayList<String>();


                                                Case 1



                                                ArrayList<String> arr it is a ArrayList reference variable with type String which reference to a ArralyList Object of Type String. It means it can hold only String type Object.



                                                It is a Strict to String not a Raw Type so, It will never raise an warning .



                                                    arr.add("hello");// alone statement will compile successfully and no warning.

                                                arr.add(23); //prone to compile time error.
                                                //error: no suitable method found for add(int)


                                                Case 2



                                                In this case ArrayList<String> arr is a strict type but your Object new ArrayList(); is a raw type.



                                                    arr.add("hello"); //alone this compile but raise the warning.
                                                arr.add(23); //again prone to compile time error.
                                                //error: no suitable method found for add(int)


                                                here arr is a Strict type. So, It will raise compile time error when adding a integer.




                                                Warning :- A Raw Type Object is referenced to a Strict type Referenced Variable of ArrayList.




                                                Case 3



                                                In this case ArrayList arr is a raw type but your Object new ArrayList<String>(); is a Strict type.



                                                    arr.add("hello");  
                                                arr.add(23); //compiles fine but raise the warning.


                                                It will add any type of Object into it because arr is a Raw Type.




                                                Warning :- A Strict Type Object is referenced to a raw type referenced Variable.








                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Jul 10 '17 at 14:14









                                                Aluan Haddad

                                                12k22549




                                                12k22549










                                                answered May 13 '16 at 13:51









                                                Vikrant Kashyap

                                                3,41411334




                                                3,41411334






















                                                    up vote
                                                    8
                                                    down vote













                                                    A raw-type is the a lack of a type parameter when using a generic type.



                                                    Raw-type should not be used because it could cause runtime errors, like inserting a double into what was supposed to be a Set of ints.



                                                    Set set = new HashSet();
                                                    set.add(3.45); //ok


                                                    When retrieving the stuff from the Set, you don't know what is coming out. Let's assume that you expect it to be all ints, you are casting it to Integer; exception at runtime when the double 3.45 comes along.



                                                    With a type parameter added to your Set, you will get a compile error at once. This preemptive error lets you fix the problem before something blows up during runtime (thus saving on time and effort).



                                                    Set<Integer> set = new HashSet<Integer>();
                                                    set.add(3.45); //NOT ok.





                                                    share|improve this answer



























                                                      up vote
                                                      8
                                                      down vote













                                                      A raw-type is the a lack of a type parameter when using a generic type.



                                                      Raw-type should not be used because it could cause runtime errors, like inserting a double into what was supposed to be a Set of ints.



                                                      Set set = new HashSet();
                                                      set.add(3.45); //ok


                                                      When retrieving the stuff from the Set, you don't know what is coming out. Let's assume that you expect it to be all ints, you are casting it to Integer; exception at runtime when the double 3.45 comes along.



                                                      With a type parameter added to your Set, you will get a compile error at once. This preemptive error lets you fix the problem before something blows up during runtime (thus saving on time and effort).



                                                      Set<Integer> set = new HashSet<Integer>();
                                                      set.add(3.45); //NOT ok.





                                                      share|improve this answer

























                                                        up vote
                                                        8
                                                        down vote










                                                        up vote
                                                        8
                                                        down vote









                                                        A raw-type is the a lack of a type parameter when using a generic type.



                                                        Raw-type should not be used because it could cause runtime errors, like inserting a double into what was supposed to be a Set of ints.



                                                        Set set = new HashSet();
                                                        set.add(3.45); //ok


                                                        When retrieving the stuff from the Set, you don't know what is coming out. Let's assume that you expect it to be all ints, you are casting it to Integer; exception at runtime when the double 3.45 comes along.



                                                        With a type parameter added to your Set, you will get a compile error at once. This preemptive error lets you fix the problem before something blows up during runtime (thus saving on time and effort).



                                                        Set<Integer> set = new HashSet<Integer>();
                                                        set.add(3.45); //NOT ok.





                                                        share|improve this answer














                                                        A raw-type is the a lack of a type parameter when using a generic type.



                                                        Raw-type should not be used because it could cause runtime errors, like inserting a double into what was supposed to be a Set of ints.



                                                        Set set = new HashSet();
                                                        set.add(3.45); //ok


                                                        When retrieving the stuff from the Set, you don't know what is coming out. Let's assume that you expect it to be all ints, you are casting it to Integer; exception at runtime when the double 3.45 comes along.



                                                        With a type parameter added to your Set, you will get a compile error at once. This preemptive error lets you fix the problem before something blows up during runtime (thus saving on time and effort).



                                                        Set<Integer> set = new HashSet<Integer>();
                                                        set.add(3.45); //NOT ok.






                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited Dec 1 '15 at 15:38









                                                        The Nail

                                                        6,61812640




                                                        6,61812640










                                                        answered May 5 '10 at 4:44









                                                        Lars Andren

                                                        6,16952948




                                                        6,16952948






















                                                            up vote
                                                            4
                                                            down vote













                                                            What is saying is that your list is a List of unespecified objects. That is that Java does not know what kind of objects are inside the list. Then when you want to iterate the list you have to cast every element, to be able to access the properties of that element (in this case, String).



                                                            In general is a better idea to parametrize the collections, so you don't have conversion problems, you will only be able to add elements of the parametrized type and your editor will offer you the appropiate methods to select.



                                                            private static List<String> list = new ArrayList<String>();





                                                            share|improve this answer

























                                                              up vote
                                                              4
                                                              down vote













                                                              What is saying is that your list is a List of unespecified objects. That is that Java does not know what kind of objects are inside the list. Then when you want to iterate the list you have to cast every element, to be able to access the properties of that element (in this case, String).



                                                              In general is a better idea to parametrize the collections, so you don't have conversion problems, you will only be able to add elements of the parametrized type and your editor will offer you the appropiate methods to select.



                                                              private static List<String> list = new ArrayList<String>();





                                                              share|improve this answer























                                                                up vote
                                                                4
                                                                down vote










                                                                up vote
                                                                4
                                                                down vote









                                                                What is saying is that your list is a List of unespecified objects. That is that Java does not know what kind of objects are inside the list. Then when you want to iterate the list you have to cast every element, to be able to access the properties of that element (in this case, String).



                                                                In general is a better idea to parametrize the collections, so you don't have conversion problems, you will only be able to add elements of the parametrized type and your editor will offer you the appropiate methods to select.



                                                                private static List<String> list = new ArrayList<String>();





                                                                share|improve this answer












                                                                What is saying is that your list is a List of unespecified objects. That is that Java does not know what kind of objects are inside the list. Then when you want to iterate the list you have to cast every element, to be able to access the properties of that element (in this case, String).



                                                                In general is a better idea to parametrize the collections, so you don't have conversion problems, you will only be able to add elements of the parametrized type and your editor will offer you the appropiate methods to select.



                                                                private static List<String> list = new ArrayList<String>();






                                                                share|improve this answer












                                                                share|improve this answer



                                                                share|improve this answer










                                                                answered Jun 16 '10 at 7:47









                                                                pakore

                                                                7,993103660




                                                                7,993103660






















                                                                    up vote
                                                                    4
                                                                    down vote













                                                                    tutorial page.



                                                                    A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                                                    public class Box<T> {
                                                                    public void set(T t) { /* ... */ }
                                                                    // ...
                                                                    }


                                                                    To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:



                                                                    Box<Integer> intBox = new Box<>();


                                                                    If the actual type argument is omitted, you create a raw type of Box:



                                                                    Box rawBox = new Box();





                                                                    share|improve this answer



























                                                                      up vote
                                                                      4
                                                                      down vote













                                                                      tutorial page.



                                                                      A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                                                      public class Box<T> {
                                                                      public void set(T t) { /* ... */ }
                                                                      // ...
                                                                      }


                                                                      To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:



                                                                      Box<Integer> intBox = new Box<>();


                                                                      If the actual type argument is omitted, you create a raw type of Box:



                                                                      Box rawBox = new Box();





                                                                      share|improve this answer

























                                                                        up vote
                                                                        4
                                                                        down vote










                                                                        up vote
                                                                        4
                                                                        down vote









                                                                        tutorial page.



                                                                        A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                                                        public class Box<T> {
                                                                        public void set(T t) { /* ... */ }
                                                                        // ...
                                                                        }


                                                                        To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:



                                                                        Box<Integer> intBox = new Box<>();


                                                                        If the actual type argument is omitted, you create a raw type of Box:



                                                                        Box rawBox = new Box();





                                                                        share|improve this answer














                                                                        tutorial page.



                                                                        A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:



                                                                        public class Box<T> {
                                                                        public void set(T t) { /* ... */ }
                                                                        // ...
                                                                        }


                                                                        To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:



                                                                        Box<Integer> intBox = new Box<>();


                                                                        If the actual type argument is omitted, you create a raw type of Box:



                                                                        Box rawBox = new Box();






                                                                        share|improve this answer














                                                                        share|improve this answer



                                                                        share|improve this answer








                                                                        edited Feb 25 '17 at 16:41

























                                                                        answered May 24 '16 at 13:42









                                                                        Mykhaylo Adamovych

                                                                        8,315175990




                                                                        8,315175990






















                                                                            up vote
                                                                            4
                                                                            down vote













                                                                            Here's another case where raw types will bite you:



                                                                            public class StrangeClass<T> {
                                                                            @SuppressWarnings("unchecked")
                                                                            public <X> X getSomethingElse() {
                                                                            return (X)"Testing something else!";
                                                                            }

                                                                            public static void main(String args) {
                                                                            final StrangeClass<String> withGeneric = new StrangeClass<>();
                                                                            final StrangeClass withoutGeneric = new StrangeClass();
                                                                            final String value1,
                                                                            value2;

                                                                            // Compiles
                                                                            value1 = withGeneric.getSomethingElse();

                                                                            // Produces compile error:
                                                                            // incompatible types: java.lang.Object cannot be converted to java.lang.String
                                                                            value2 = withoutGeneric.getSomethingElse();
                                                                            }
                                                                            }


                                                                            As was mentioned in the accepted answer, you lose all support for generics within the code of the raw type. Every type parameter is converted to its erasure (which in the above example is just Object).






                                                                            share|improve this answer



























                                                                              up vote
                                                                              4
                                                                              down vote













                                                                              Here's another case where raw types will bite you:



                                                                              public class StrangeClass<T> {
                                                                              @SuppressWarnings("unchecked")
                                                                              public <X> X getSomethingElse() {
                                                                              return (X)"Testing something else!";
                                                                              }

                                                                              public static void main(String args) {
                                                                              final StrangeClass<String> withGeneric = new StrangeClass<>();
                                                                              final StrangeClass withoutGeneric = new StrangeClass();
                                                                              final String value1,
                                                                              value2;

                                                                              // Compiles
                                                                              value1 = withGeneric.getSomethingElse();

                                                                              // Produces compile error:
                                                                              // incompatible types: java.lang.Object cannot be converted to java.lang.String
                                                                              value2 = withoutGeneric.getSomethingElse();
                                                                              }
                                                                              }


                                                                              As was mentioned in the accepted answer, you lose all support for generics within the code of the raw type. Every type parameter is converted to its erasure (which in the above example is just Object).






                                                                              share|improve this answer

























                                                                                up vote
                                                                                4
                                                                                down vote










                                                                                up vote
                                                                                4
                                                                                down vote









                                                                                Here's another case where raw types will bite you:



                                                                                public class StrangeClass<T> {
                                                                                @SuppressWarnings("unchecked")
                                                                                public <X> X getSomethingElse() {
                                                                                return (X)"Testing something else!";
                                                                                }

                                                                                public static void main(String args) {
                                                                                final StrangeClass<String> withGeneric = new StrangeClass<>();
                                                                                final StrangeClass withoutGeneric = new StrangeClass();
                                                                                final String value1,
                                                                                value2;

                                                                                // Compiles
                                                                                value1 = withGeneric.getSomethingElse();

                                                                                // Produces compile error:
                                                                                // incompatible types: java.lang.Object cannot be converted to java.lang.String
                                                                                value2 = withoutGeneric.getSomethingElse();
                                                                                }
                                                                                }


                                                                                As was mentioned in the accepted answer, you lose all support for generics within the code of the raw type. Every type parameter is converted to its erasure (which in the above example is just Object).






                                                                                share|improve this answer














                                                                                Here's another case where raw types will bite you:



                                                                                public class StrangeClass<T> {
                                                                                @SuppressWarnings("unchecked")
                                                                                public <X> X getSomethingElse() {
                                                                                return (X)"Testing something else!";
                                                                                }

                                                                                public static void main(String args) {
                                                                                final StrangeClass<String> withGeneric = new StrangeClass<>();
                                                                                final StrangeClass withoutGeneric = new StrangeClass();
                                                                                final String value1,
                                                                                value2;

                                                                                // Compiles
                                                                                value1 = withGeneric.getSomethingElse();

                                                                                // Produces compile error:
                                                                                // incompatible types: java.lang.Object cannot be converted to java.lang.String
                                                                                value2 = withoutGeneric.getSomethingElse();
                                                                                }
                                                                                }


                                                                                As was mentioned in the accepted answer, you lose all support for generics within the code of the raw type. Every type parameter is converted to its erasure (which in the above example is just Object).







                                                                                share|improve this answer














                                                                                share|improve this answer



                                                                                share|improve this answer








                                                                                edited Oct 31 at 13:40

























                                                                                answered Dec 4 '17 at 4:49









                                                                                GuyPaddock

                                                                                37047




                                                                                37047






















                                                                                    up vote
                                                                                    1
                                                                                    down vote













                                                                                    I found this page after doing some sample exercises and having the exact same puzzlement.



                                                                                    ============== I went from this code as provide by the sample ===============



                                                                                    public static void main(String args) throws IOException {

                                                                                    Map wordMap = new HashMap();
                                                                                    if (args.length > 0) {
                                                                                    for (int i = 0; i < args.length; i++) {
                                                                                    countWord(wordMap, args[i]);
                                                                                    }
                                                                                    } else {
                                                                                    getWordFrequency(System.in, wordMap);
                                                                                    }
                                                                                    for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                    Map.Entry entry = (Map.Entry) i.next();
                                                                                    System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                    }


                                                                                    ====================== To This code ========================



                                                                                    public static void main(String args) throws IOException {
                                                                                    // replace with TreeMap to get them sorted by name
                                                                                    Map<String, Integer> wordMap = new HashMap<String, Integer>();
                                                                                    if (args.length > 0) {
                                                                                    for (int i = 0; i < args.length; i++) {
                                                                                    countWord(wordMap, args[i]);
                                                                                    }
                                                                                    } else {
                                                                                    getWordFrequency(System.in, wordMap);
                                                                                    }
                                                                                    for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                    Entry<String, Integer> entry = i.next();
                                                                                    System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                    }

                                                                                    }


                                                                                    ===============================================================================



                                                                                    It may be safer but took 4 hours to demuddle the philosophy...






                                                                                    share|improve this answer



























                                                                                      up vote
                                                                                      1
                                                                                      down vote













                                                                                      I found this page after doing some sample exercises and having the exact same puzzlement.



                                                                                      ============== I went from this code as provide by the sample ===============



                                                                                      public static void main(String args) throws IOException {

                                                                                      Map wordMap = new HashMap();
                                                                                      if (args.length > 0) {
                                                                                      for (int i = 0; i < args.length; i++) {
                                                                                      countWord(wordMap, args[i]);
                                                                                      }
                                                                                      } else {
                                                                                      getWordFrequency(System.in, wordMap);
                                                                                      }
                                                                                      for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                      Map.Entry entry = (Map.Entry) i.next();
                                                                                      System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                      }


                                                                                      ====================== To This code ========================



                                                                                      public static void main(String args) throws IOException {
                                                                                      // replace with TreeMap to get them sorted by name
                                                                                      Map<String, Integer> wordMap = new HashMap<String, Integer>();
                                                                                      if (args.length > 0) {
                                                                                      for (int i = 0; i < args.length; i++) {
                                                                                      countWord(wordMap, args[i]);
                                                                                      }
                                                                                      } else {
                                                                                      getWordFrequency(System.in, wordMap);
                                                                                      }
                                                                                      for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                      Entry<String, Integer> entry = i.next();
                                                                                      System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                      }

                                                                                      }


                                                                                      ===============================================================================



                                                                                      It may be safer but took 4 hours to demuddle the philosophy...






                                                                                      share|improve this answer

























                                                                                        up vote
                                                                                        1
                                                                                        down vote










                                                                                        up vote
                                                                                        1
                                                                                        down vote









                                                                                        I found this page after doing some sample exercises and having the exact same puzzlement.



                                                                                        ============== I went from this code as provide by the sample ===============



                                                                                        public static void main(String args) throws IOException {

                                                                                        Map wordMap = new HashMap();
                                                                                        if (args.length > 0) {
                                                                                        for (int i = 0; i < args.length; i++) {
                                                                                        countWord(wordMap, args[i]);
                                                                                        }
                                                                                        } else {
                                                                                        getWordFrequency(System.in, wordMap);
                                                                                        }
                                                                                        for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                        Map.Entry entry = (Map.Entry) i.next();
                                                                                        System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                        }


                                                                                        ====================== To This code ========================



                                                                                        public static void main(String args) throws IOException {
                                                                                        // replace with TreeMap to get them sorted by name
                                                                                        Map<String, Integer> wordMap = new HashMap<String, Integer>();
                                                                                        if (args.length > 0) {
                                                                                        for (int i = 0; i < args.length; i++) {
                                                                                        countWord(wordMap, args[i]);
                                                                                        }
                                                                                        } else {
                                                                                        getWordFrequency(System.in, wordMap);
                                                                                        }
                                                                                        for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                        Entry<String, Integer> entry = i.next();
                                                                                        System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                        }

                                                                                        }


                                                                                        ===============================================================================



                                                                                        It may be safer but took 4 hours to demuddle the philosophy...






                                                                                        share|improve this answer














                                                                                        I found this page after doing some sample exercises and having the exact same puzzlement.



                                                                                        ============== I went from this code as provide by the sample ===============



                                                                                        public static void main(String args) throws IOException {

                                                                                        Map wordMap = new HashMap();
                                                                                        if (args.length > 0) {
                                                                                        for (int i = 0; i < args.length; i++) {
                                                                                        countWord(wordMap, args[i]);
                                                                                        }
                                                                                        } else {
                                                                                        getWordFrequency(System.in, wordMap);
                                                                                        }
                                                                                        for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                        Map.Entry entry = (Map.Entry) i.next();
                                                                                        System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                        }


                                                                                        ====================== To This code ========================



                                                                                        public static void main(String args) throws IOException {
                                                                                        // replace with TreeMap to get them sorted by name
                                                                                        Map<String, Integer> wordMap = new HashMap<String, Integer>();
                                                                                        if (args.length > 0) {
                                                                                        for (int i = 0; i < args.length; i++) {
                                                                                        countWord(wordMap, args[i]);
                                                                                        }
                                                                                        } else {
                                                                                        getWordFrequency(System.in, wordMap);
                                                                                        }
                                                                                        for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
                                                                                        Entry<String, Integer> entry = i.next();
                                                                                        System.out.println(entry.getKey() + " :t" + entry.getValue());
                                                                                        }

                                                                                        }


                                                                                        ===============================================================================



                                                                                        It may be safer but took 4 hours to demuddle the philosophy...







                                                                                        share|improve this answer














                                                                                        share|improve this answer



                                                                                        share|improve this answer








                                                                                        edited Mar 7 '16 at 2:43









                                                                                        Pang

                                                                                        6,8501563101




                                                                                        6,8501563101










                                                                                        answered Mar 7 '16 at 2:24









                                                                                        user2442615

                                                                                        213




                                                                                        213






















                                                                                            up vote
                                                                                            0
                                                                                            down vote













                                                                                            Raw types are fine when they express what you want to express.



                                                                                            For example, a deserialisation function might return a List, but it doesn't know the list's element type. So List is the appropriate return type here.






                                                                                            share|improve this answer





















                                                                                            • You can use ? as type parameter
                                                                                              – Dániel Kis
                                                                                              Dec 27 '17 at 19:29










                                                                                            • Yes, but that is more to type and I am against typing more. :)
                                                                                              – Stefan Reich
                                                                                              Dec 31 '17 at 18:37















                                                                                            up vote
                                                                                            0
                                                                                            down vote













                                                                                            Raw types are fine when they express what you want to express.



                                                                                            For example, a deserialisation function might return a List, but it doesn't know the list's element type. So List is the appropriate return type here.






                                                                                            share|improve this answer





















                                                                                            • You can use ? as type parameter
                                                                                              – Dániel Kis
                                                                                              Dec 27 '17 at 19:29










                                                                                            • Yes, but that is more to type and I am against typing more. :)
                                                                                              – Stefan Reich
                                                                                              Dec 31 '17 at 18:37













                                                                                            up vote
                                                                                            0
                                                                                            down vote










                                                                                            up vote
                                                                                            0
                                                                                            down vote









                                                                                            Raw types are fine when they express what you want to express.



                                                                                            For example, a deserialisation function might return a List, but it doesn't know the list's element type. So List is the appropriate return type here.






                                                                                            share|improve this answer












                                                                                            Raw types are fine when they express what you want to express.



                                                                                            For example, a deserialisation function might return a List, but it doesn't know the list's element type. So List is the appropriate return type here.







                                                                                            share|improve this answer












                                                                                            share|improve this answer



                                                                                            share|improve this answer










                                                                                            answered Dec 4 '17 at 12:58









                                                                                            Stefan Reich

                                                                                            429411




                                                                                            429411












                                                                                            • You can use ? as type parameter
                                                                                              – Dániel Kis
                                                                                              Dec 27 '17 at 19:29










                                                                                            • Yes, but that is more to type and I am against typing more. :)
                                                                                              – Stefan Reich
                                                                                              Dec 31 '17 at 18:37


















                                                                                            • You can use ? as type parameter
                                                                                              – Dániel Kis
                                                                                              Dec 27 '17 at 19:29










                                                                                            • Yes, but that is more to type and I am against typing more. :)
                                                                                              – Stefan Reich
                                                                                              Dec 31 '17 at 18:37
















                                                                                            You can use ? as type parameter
                                                                                            – Dániel Kis
                                                                                            Dec 27 '17 at 19:29




                                                                                            You can use ? as type parameter
                                                                                            – Dániel Kis
                                                                                            Dec 27 '17 at 19:29












                                                                                            Yes, but that is more to type and I am against typing more. :)
                                                                                            – Stefan Reich
                                                                                            Dec 31 '17 at 18:37




                                                                                            Yes, but that is more to type and I am against typing more. :)
                                                                                            – Stefan Reich
                                                                                            Dec 31 '17 at 18:37





                                                                                            protected by Luiggi Mendoza Oct 12 '13 at 17:37



                                                                                            Thank you for your interest in this question.
                                                                                            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                                            Would you like to answer one of these unanswered questions instead?



                                                                                            Popular posts from this blog

                                                                                            Wiesbaden

                                                                                            Marschland

                                                                                            Dieringhausen