B
General rules on how to deal with warningsObviously, the purpose of @SuppressWarnings is to make the compiler not issue warnings. However using it properly requires good-feeling. Here are some rules on how to use it properly:When faced with a warning in particular, try to understand what the cause first. Don't go out putting @SuppressWarnings anyway on anything!Try to eliminate warnings when changing the code to make it disappear, i.e. correct the problem warning is saying you have. See below here in my answer how to deal with the most common cases.If you can't eliminate one warning in particular, think if you really want to suppress it. Sometimes letting the compiler keep yelling insistently every time you compile the code is better than muting it, because in the future, if/when someone/you have a solution warning She won't be forgotten. Moreover, warning always serves as a reminder that there are some pending resolution technical debits.If you really want to silence warning, place the @SuppressWarnings in the lowest possible scope. That is, if you can put it in a local variable instead of putting it in the whole method, prefer to place it in the local variable.If you put one @SuppressWarnings in your code, it is good to put a comment (with // ... or /* ... */) explaining why you are suppressing one warning in particular, unless it is a very obvious case.If you are to make changes to some code that uses @SuppressWarnings, see this as a potential opportunity to remove the @SuppressWarnings. Always take a look if by changing the code, you do not end up eliminating/correcting the stitution that generates the warning, and therefore no longer needing to suppress it.And the most common cases where warnings can be eliminated are:1. Warning. uncheckedThis is the most common case, and it can often happen when generic types do not match, but still you can ensure that the program works.A warning unchecked is fired more often in casts. General casts are checked in runtime, but with generic types, due to type-erasure, the verification of the generic type is not carried out in runtime, being restricted only to the base type. For example:public List<?> devolveAlgumaLista() {
if (condicaoQualquer) {
return new ArrayList<Gato>();
} else {
return new ArrayList<Cachorro>();
}
}
@SuppressWarnings("unchecked")
public void metodoQualquer() {
List<?> lista = devolveAlgumaLista();
if (outraCondicao) {
for (Cachorro c : (List<Cachorro>) lista) { // Cast unchecked.
System.out.println(c.latir());
}
} else {
for (Gato g : (List<Gato>) lista) { // Cast unchecked.
System.out.println(g.miar());
}
}
}
Another example:public List metodoBemAntigoEmAlgumaBiblioteca() {
// ...
}
public void meuMetodoNovo() {
@SuppressWarnings("unchecked")
List<Abacaxi> lista = (List<Abacaxi>) metodoBemAntigoEmAlgumaBiblioteca();
}
Another place where it can occur is in generic arrays:public <T> void metodo() {
T[] array = ...; // warning unchecked
}
And this is because the generic type is lost because of the type-erasure, which allows me to insert in the array elements that violate the type restrictions that the compiler imposes (what is called the heap pollution). O heap pollution can also happen with lists, maps and other data structures when the rules of the generics are violated. When your application suffers from heap pollution, the most common result is you have ClassCastExceptions being thrown into unexpected places.Having a return of methods, parameters or variables whose types depend on circumstances that cannot be verified by the compiler in general is not a good idea, and the ideal is that the code is restructured in order to ensure that the compiler has a way to verify types properly. Generic Arrays are rarely a good idea too. However, from time to time this situation happens in a way which is not possible to avoid, and that is why we have the @SuppressWarnings("unchecked").To eliminate this warning, the ideal is:Study very well General and learn to use them also to create generic classes, including how to use coring types (such as List<? super Foo>). Many of the places where to warning unchecked appears is the result of code developed by people who do not know how to properly use the General.Understand what is heap pollution, for it is exactly against that which warning unchecked Try to alert.Do not use gross types (such as List and Map rather than List<Foo> and Map<Foo, Bar>). Always try to declare all required generic types, even if some of them are coring types (with <?>) or are variables of types.Using methods java.util.Collections.checked* in collections and maps where generic types are simple, such as java.util.Collections.checkedList(lista, String.class).Avoid mixing arrays with generic types. The best is to work with lists or with some other type of data structure, even more than arrays are a low-level data structure and ideally should be abstracted if possible. The method java.util.Arrays.asList(T... a) is very useful in these circumstances.Avoid declaring type parameters Object and type returns Object. When this happens, it may be that using a generic type would be better than using Object.Using methods java.lang.Class.cast(Class<U> c) and java.lang.Class.asSubclass(Class<S> c). With these methods it is possible to implement casts dynamic in runtime.Don't do it casts for types variables (such as return (T) obj;). If possible, use the object Class suitable for this (as in return classT.cast(obj);).Declare parameters with a generic type Class<X>, where X is a type variable declared in the method in question.Avoid creating heterogeneous data structures (i.e., which can contain more than one type of object, such as a list containing a mixture of cats and dogs).If you really need to mix arrays with generic types instead of using a List or one Map, make sure you know very well what you are doing.And of course, if none of the alternatives are possible, then the solution would be to use the @SuppressWarnings("unchecked").2. Warning. rawtypesSimilar to @SuppressWarnings("unchecked"), this one happens when rough guys are declared. Gross types are those types should be generic, but in which generics were not used, typically due to the use of legacy classes prior to Java 5.For example:public void meuMetodo() {
List elementos = ...; // warning rawtypes
// ...
}
The solution for warnings of this type are the same as that unchecked, only the specific situation in which it occurs is a little different. And obviously, there are cases where it can't be eliminated, and so the @SuppressWarnings("rawtypes") can be used.3. Warning. deprecationThis one happens when you use a method deprecated or overwrite a method deprecated. For example: public void fazerAlgo() {
JPasswordField jf = // ...
String x = jf.getText(); // warning deprecation
// ...
}
To eliminate this warning, the ideal is:Do not use method, attribute or class deprecated, after all it was marked as deprecated is because there is some reason not to be used. And when that happens, there is usually something else that should be used in place.If the method or class you are implementing/coding/change is also deprecated, then mark the method (or perhaps even the whole class) with @Deprecated.4. Warning. dep-annIf the method, class, field or constructor you are implementing/coding/changed has a javadoc with a tag @deprecated, but without the annotation @Deprecated, you will receive a warning dep-ann. To correct it just add annotation @Deprecated.In general, there is no sense in ignoring the warning dep-ann, even more than fixing it is easy. The only situation where you can't fix it is in code that you should maintain compatibility with versions of the java prior to 5 and therefore cannot have notes. But in this case, you also cannot suppress the warning with @SuppressWarnings.Five. Warning. hidingThis is what happens when two variables with the same name are declared, but both present in the same scope, as in the code below:public class MinhaClasse {
private int x;
public void metodo() {
int x = 25; // warning hiding
// ...
}
}
Having two variables with the same name visible in the same scope is a bad programming practice (only setters in general they are forgiven, but there are those who disagree with it, including me).To correct this warning, the ideal is to rename one of the variables that is colliding. And it's easier to rename the one with the lowest scope. In the case of local variables, there is no reason for this correction not to be made. It is rare that a correction is not possible, as in the case of the internal class having a public attribute with the same name as a public attribute in the external class. And in general, when some more complex case hiding happens, it is a sign that you have much bigger problems in your code. But if you can't fix it, then use the @SuppressWarnings("hiding").6. Warning. unusedIt occurs when you have methods, fields, builders or internal classes (generally private) that are not used. It can also occur with local parameters and variables that are not used.In the case of local variables, there is no excuse to keep them, the best is just to eliminate them.In the case of fields, methods, builders and private internal classes that seem not to be used, the ideal is only to eliminate them.In the case of parameters, except in the case of overriding or parameters that must remain to ensure compatibility, the ideal is to eliminate them.In cases where a field, constructor, method or private and apparently never used internal class can be accessed through reflection, in this case it is valid to use @SuppressWarnings("unused").7. Warning. varargsYou have declared a parameter that is a vararg array of a generic type, which can bring you problems heap pollution (see item of unchecked). In general the solution for this is to try to use a List or one Map instead of the array, or use the java.util.Arrays.asList(T...). Also it is worth taking a look at the annotation @SafeVarargs. Only if none of these options are valid, is that @SuppressWarnings("varargs") must be considered.Eight. Warning. fallthroughO switch already is a horrifying language construction that Java inherited from C. Pior is still having inherited the fallthrough. In most cases where this occurs, it is because you forgot one break (or perhaps one throw or return) in your switch, and in this case what you have to do is fix the error.Even when fallthrough is intentional, using it in general is a bad programming practice, and you should encode your switch so as not to need fallthrough, or even in a way that does not need switch. A way you don't need switch it's trying to each turn case in an overwrite of an abstract polymorphic method and summon it instead of doing switch. From Java 8, you can find ways to replace with some lambdas expressions, although this is somewhat difficult in the case of fallthrough.But if fallthrough it is really necessary and you cannot eliminate it (or at least, not easily), put it @SuppressWarnings("fallthrough").9. Warning. restrictionYou are using some class that is not part of the public API and should not be used directly, such as those in the packages sun.*. And the best solution is simply not to use this class and use any alternative that is not in a prohibited package. If you are trying to decide in runtime if it will be used, or if an alternative will be sought, the ideal is to access it only via reflection.However, if you have no choice but to use such a class and do not just want to leave the compiler complaining always, then the way is to use the @SuppressWarnings("restriction").10. Warning. serialYou have defined a serializable class that does not have the serialVersionUID. A serializable class is one that implements the interface java.io.Serializable, even if indirectly (i.e. implements an interface that inherits from java.io.Serializable or else inherit from a class that implements java.io.Serializable).In cases where you do not care about serialization, it is safe to suppress this warning. But it is better if instead, you just declare the field serialVersionUID adequately.11. Warning. castYou're using one cast unnecessary in code (such as doing String x = (String) "Hello World";). In this case the ideal is simply to remove cast. It's hard to imagine a case where this is warning should be suppressed rather than just corrected.12. Other warningsThere are many others warnings. See these links: http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html#BHCJBHDF https://stackoverflow.com/a/1206001/540552 https://jazzy.id.au/2008/10/30/list_of_suppresswarnings_arguments.html (outdated, feel free to edit if you find a better reference)Other tools such as https://en.wikipedia.org/wiki/Checkstyle , https://en.wikipedia.org/wiki/FindBugs and http://types.cs.washington.edu/checker-framework/ also have their specific warnings.For these warnings more specific, check the relevant documentation to understand what is happening, and how to eliminate the problem or else and whether it is pertinent or not to use @SuppressWarnings.Many of these warnings are simple to correct and has no sense in being ignored, such as empty, dep-ann and cast. Others may be just compiler's annoyance, and in this case, if they cannot be corrected, the best is to ignore them, such as unqualified-field-access, serial and processing. However, there are always some that are important and can be difficult to arrange, such as unchecked, finally and fallthrough. But remember, always try first to correct warning, and only if you can't correct and even find it better to let the compiler continue to complain, do you think about muting it with the @SuppressWarnings.13. @SuppressWarnings("all")Use @SuppressWarnings("all") is the last resort, for it silences all warnings. Ideally you should not use @SuppressWarnings("all") never, but there are two cases that come to my mind in which it makes sense:The class is automatically generated and managed by some tool before or during the build process, and because of this, it is not desirable that the compiler is complaining of warnings in her.The class has been copied and glued from somewhere else or has been received from somewhere else and for some reason it should not suffer any change (which is not the change of adding its own @SuppressWarnings). In this case, it is better to silence all warnings that the compiler is to issue about this class.