compiler unchecked warnings -java


Friends! if you like this post ,please comment below and share it to your friends :)

Under The Hood Of The Compiler

 

Compiler Messages


What is an "unchecked" warning?

A warning by which the compiler indicates that it cannot ensure type safety.
The term "unchecked" warning is misleading.  It does not mean that the warning is unchecked in any way.  The term "unchecked" refers to the fact that the compiler and the runtime system do not have enough type information to perform all type checks that would be necessary to ensure type safety. In this sense, certain operations are "unchecked". The most common source of "unchecked" warnings is the use of raw types.  "unchecked" warnings are issued when an object is accessed through a raw type variable, because the raw type does not provide enough type information to perform all necessary type checks.
Example (of unchecked warning in conjunction with raw types):
 TreeSet set = new TreeSet();
set.add("abc");        // unchecked warning
set.remove("abc");


warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.TreeSet
               set.add("abc"); 
                      ^
When the add method is invoked the compiler does not know whether it is safe to add a String object to the collection.  If the TreeSet is a collection that contains String s (or a supertype thereof), then it would be safe.  But from the type information provided by the raw type TreeSet the compiler cannot tell.  Hence the call is potentially unsafe and an "unchecked" warning is issued.
 "unchecked" warnings are also reported when the compiler finds a cast whose target type is either a parameterized type or a type parameter.
Example (of an unchecked warning in conjunction with a cast to a parameterized type or type variable):
class Wrapper<T> { 
  private T wrapped ; 
  public Wrapper (T arg) {wrapped = arg;} 
  ... 
  p ublic Wrapper <T> clone() { 
    Wrapper<T> clon = null; 
     try {  
       clon = (Wrapper<T>) super.clone(); // unchecked warning 
     } catch (CloneNotSupportedException e) {  
       throw new InternalError();  
     } 
     try {  
       Class<?> clzz = this.wrapped.getClass(); 
       Method   meth = clzz.getMethod("clone", new Class[0]); 
       Object   dupl = meth.invoke(this.wrapped, new Object[0]); 
       clon.wrapped = (T) dupl; // unchecked warning 
     } catch (Exception e) {} 
     return clon; 
  } 
} 


warning: [unchecked] unchecked cast
found   : java.lang.Object
required: Wrapper <T>
                  clon = ( Wrapper <T>)super.clone(); 
                                                ^
warning: [unchecked] unchecked cast
found   : java.lang.Object
required: T
                  clon. wrapped = (T)dupl; 
                                    ^
A cast whose target type is either a (concrete or bounded wildcard) parameterized type or a type parameter is unsafe, if a dynamic type check at runtime is involved.  At runtime, only the type erasure is available, not the exact static type that is visible in the source code.  As a result, the runtime part of the cast is performed based on the type erasure, not on the exact static type. In the example, the cast to Wrapper<T> would check whether the object returned from super.clone is a Wrapper , not whether it is a wrapper with a particular type of members.  Similarly, the casts to the type parameter are cast to type Object at runtime, and probably optimized away altogether.  Due to type erasure, the runtime system is unable to perform more useful type checks at runtime.
In a way, the source code is misleading, because it suggests that a cast to the respective target type is performed, while in fact the dynamic part of the cast only checks against the type erasure of the target type.  The "unchecked" warning is issued to draw the programmer's attention to this mismatch between the static and dynamic aspect of the cast.



How can I disable or enable "unchecked" warnings? 
Via the compiler options -Xlint:unchecked and -Xlint:-unchecked and via the standard annotation @SuppressWarnings("unchecked") .
The compiler option -Xlint:-unchecked disables all unchecked warnings that would occur in a compilation. The annotation @SuppressWarnings("unchecked") suppresses all warnings for the annotated part of the program.
Note, in the first release of Java 5.0 the SuppressWarnings annotation is not yet supported.




What is the -Xlint:unchecked compiler option?

The compiler option -Xlint:unchecked enables "unchecked" warnings, the option -Xlint:-unchecked disables all unchecked warnings.
"unchecked" warnings are by default disabled.  If you compile a program with no particular compiler options then the compiler will not report any "unchecked" warnings. If the compiler finds source code for which it would want to report an "unchecked" warning it only gives a general hint.  You will find the following note at the end of the list of all other errors and warnings:
Note: util/Wrapper.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
If you want to see the "unchecked" warnings you must start the compiler with the -Xlint:unchecked option. Example (of globally enabling unchecked warnings):
javac -Xlint:unchecked util/Wrapper.java
The option -Xlint:unchecked en ables the "unchecked" warnings. The "unchecked" warnings are also enabled when you use the -Xlint:all option. The option -Xlint:-unchecked disables the "unchecked" warnings.  This is useful to suppress all  "unchecked" warnings, while other types of warnings remain enabled.
Example (of globally disabling unchecked warnings):
javac -g -source 1.5 -Xlint:all -Xlint:-unchecked util/Wrapper.java
In this example, using -Xlint:all all warnings (such as "unchecked", "deprecated", "fallthrough", etc.) are enabled and subsequently the "unchecked" warnings are disabled using -Xlint:-unchecked . As a result all warnings except "unchecked" warnings will be reported.

What is the SuppressWarnings annotation?

A standard annotation in java that suppresses warnings for the annotated part of the program.
The compiler supports a number of standard annotations (see package java.lang.annotation ). Among them is the SuppressWarnings annotation. It contains a list of warning labels.  If a definition in the source code is annotated with the SuppressWarnings annotation, then all warnings, whose labels appear in the annotation's list of warning labels, are suppressed for the annotated definition or any of its parts. The SuppressWarnings annotation can be used to suppress any type of labelled warning.  In particular we can use the annotation to suppress "unchecked" warnings.
Example (of suppressing unchecked warnings):
@SuppressWarnings("unchecked") 
class Wrapper<T> { 
  private T wrapped ; 
  public Wrapper (T arg) {wrapped = arg;} 
  ... 
  p ublic Wrapper <T> clone() { 
    Wrapper<T> clon = null; 
     try {  
       clon = (Wrapper<T>) super.clone(); // unchecked warning supressed 
     } catch (CloneNotSupportedException e) {  
       throw new InternalError(); 
     } 
     try {  
       Class<?> clzz = this.wrapped.getClass(); 
       Method   meth = clzz.getMethod("clone", new Class[0]); 
       Object   dupl = meth.invoke(this.wrapped, new Object[0]); 
       clon.wrapped = (T) dupl; // unchecked warning supressed 
     } catch (Exception e) {} 
     return clon; 
  } 
}
This example would usually raise 2 "unchecked" warnings.  Since we annotated the entire class, all unchecked warnings raised anywhere in the class implementation are suppressed. We can suppress several types of annotations at a time.  In this case we must specify a list of warning labels.
Example (of suppressing several types of warnings):
@SuppressWarnings(value={"unchecked","deprecation"}) 
public static void someMethod() { 
  ... 
  TreeSet se t = new TreeSet();
  set.add(new Date(104,8,11));     // unchecked and deprecation warning suppressed 
  ... 
}
This example would usually raise 2 warnings when the call to method add is compiled:
warning: [deprecation] Date(int,int,int) in java.util.Date has been deprecated
        set.add(new Date(104,8,11));
                ^
warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.TreeSet
        set.add(new Date(104,8,11));
 The annotation preceding the enclosing method suppresses all unchecked and deprecation warnings anywhere in the method implementation. Annotations can not be attached to statements, expressions, or blocks, only to program entities with a definition like types, variables, etc.
Example (of illegal placement of annotation):
public static void someMethod() { 
  ... 
  TreeSet se t = new TreeSet(); 
  @SuppressWarnings(value={"unchecked"}) // error 
  set.add(new Date(104,8,11)); 
  ... 
}
Annotations can be attached to the definition of packages, classes, interfaces, fields, methods, parameters, constructors, local variables, enum types, enum constants, and  annotation types. An annotated package declaration must go into a file named package-info.java in the directory that represents the package. Note, in release of Java 5.0 the SuppressWarnings annotation is not yet supported by all compilers. Sun's compiler will support in in release 6.0. 


How can I avoid "unchecked cast" warnings?

By using an unbounded wildcard parmeterized type as target type of a cast expression.
Occasionally, we would like to cast to a parameterized type, just to discover that the compiler flags it with an "unchecked" warning. As we are interested in warning-free compilation of our source code, we would like to avoid this warning.  Use of an unbounded wildcard parameterized type instead of a concrete or a bounded wildcard parameterized type would help avoid the warning. A typical example is the implementation of methods such as the equals method, that take Object reference and where a cast down to the actual type must be performed.
Example (not recommended):
class Wrapper<T> {
  private T wrapped;
    ...
  public boolean equals (Object other) { 
    ... 
    Wrapper<T> otherWrapper = (Wrapper<T>) other; // warning; unchecked cast 
    return (this.wrapped.equals(otherWrapper.wrapped));
  }
}
When we replace the cast to Wrapper<T> by a cast to Wrapper<?> the warning disappears, because unbounded wildcard parameterized types are permitted as target type of a cast without any warnings. Example (implementation of equals ):
class Wrapper<T> {
  private T wrapped;
    ...
  public boolean equals (Object other) { 
    ... 
    Wrapper<?> otherWrapper = (Wrapper<?>) other; 
    return (this.wrapped.equals(otherWrapper.wrapped));
  }
}
Note, this technique works in this example only because we need no write access to the fields of the object refered to through the wildcard parameterized type and we need not invoke any methods.  Remember, use of the object that a wildcard reference variable refers to is restricted.  In other situations use of a wildcard parameterized type might not be a viable solution, because full access to the referenced object is needed. 


Is it possible to eliminate all "unchecked" warnings?

Almost.
"Unchecked" warnings stem either from using generic types in their raw form or from casts whose target type is a type parameter or a concrete or bounded wildcard parameterized type. If you refrain from both using raw types and the critical casts you can theoretically eliminate all "unchecked" warnings.  Whether this is doable in practice depends on the circumstances. Raw types.
When source code is compiled for use in Java 5.0 that was developed before Java 5.0 and uses classes that are generic in Java 5.0, then "unchecked" warnings are inevitable.  For instance, if "legacy" code uses types such as List , which used to be a regular (non-generic) types before Java 5.0, but are generic in Java 5.0, all these uses of List are considered uses of a raw type in Java 5.0.  Use of the raw types will lead to "unchecked" warnings.  If you want to eliminate the "unchecked" warnings you must re-engineer the "legacy" code and replace all raw uses of List with appropriate instantiations of List such as List<String> , List<Object> , List<?> , etc.  All "unchecked" warnings can be eliminated this way.
In source code developed for Java 5.0 you can prevent "unchecked" warnings in the first place by never using raw types.  Always provide type arguments when you use a generic type.  There are no situations in which you are forced to use a raw type.  In case of doubt, when you feel you have no idea which type argument would be appropriate, try the unbounded wildcard " ? ".
In essence, "unchecked" warnings due to use of raw types can be eliminated if you have access to legacy code and are willing to re-engineer it.
Casts.
"Unchecked" warnings as a result of cast expressions can be eliminated by eliminating the offensive casts.  Eliminating such casts is almost always possible.  There are, however, a few situations where a cast to a type parameter or a concrete or bounded wildcard parameterized type cannot be avoided.
These are typically situations where a method returns a supertype reference to an object of a more specific type. The classic example is the clone method; it returns an Object reference to an object of the type on which it was invoked. In order to recover the returned object's actual type a cast in necessary.  If the cloned object is of a parameterized type, then the target type of the cast is an instantiation of that parameterized type, and an "unchecked" warning is inevitable.  The clone method is just one example that leads to unavoidable "unchecked" warnings. Invocation of methods via reflection has similar effects because the return value of a reflectively invoked method is returned via an Object reference.  It is likely that you will find further examples of unavoidable "unchecked" casts in practice. 


Why do I get an "unchecked" warning although there is no type information missing?

Because the compiler performs all type checks based on the type erasure when you use a raw type.
Usually the compiler issues an "unchecked" warning in order to alert you to some type-safety hazard that the compiler cannot prevent because there is not enough type information available. One of these situations is the invocation of methods of a raw type.Example (of unchecked warning in conjunction with raw types):
class TreeSet<E> {
  boolean add(E o) { ...  }
} 
TreeSet se t = new TreeSet();
set.add("abc");        // unchecked warning 

warning: [unchecked] unchecked call to add(E) as a member of the raw type TreeSet
               set.add("abc"); 
                      ^
When the add method is invoked the compiler does not know whether it is safe to add a String object to the collection because the raw type  TreeSet does not provide any information regarding the type of the contained elements.Curiously, an unchecked warning is also issued in situations where there is enough type information available.
Example (of a spurious unchecked warning in conjunction with raw types):

class SomeType<T> {
  public List<String> getList() { ...  }
}
SomeType raw = new  SomeType ();
List<String> listString = raw.getList();  // unchecked warning 


warning: [unchecked] unchecked conversion
found   : List
required: List<String>
        List<String> listString = raw.getList(); 
                                             ^ 
In this example, there is no type information missing.  The  getList method is declared to return a  List<String> and this is so even in the raw type because the method does not depend on the enclosing class's type parameter.  Yet the compiler complains. The reason is that the compiler computes the type erasure of a generic type when it finds an occurrence of the raw type in the source code.  Type erasure does not only elide all occurances of the type parameter  T , but also elides the type argument of the  getList method's return type. After type erasure, the  getList method returns just a  List and no longer a  List<String>.  All subsequent type checks are performed based on the type erasure; hence the "unchecked" warning.
The "unchecked" warning can easily be avoided by refraining from use of the raw type.  SomeType is a generic type and should always be used with a type argument. In general, the use of raw types will inevitably result in "unchecked" warnings; some of the warnings may be spurious, but most of them are justified.

Note, that no spurious warning is issued when the method in question is a static method.Example (of invoking a static method of a raw type):

class SomeType<T> {
  public  static List<String> getList() { ...  }
}
SomeType raw = new  SomeType ();
List<String> listString = raw.getList();  // fine
nothing
 

Comments

Popular posts from this blog

merge sort easy and best program and algorithm in c++