As a developer working with Java, you have surely met this warning before: "uses unchecked or unsafe operations". In this blog, we'll discover what is "uses unchecked or unsafe operations" and how to resolve it.
What is Java warning: uses unchecked or unsafe operations
"Uses unchecked or unsafe operations" is a compilation warning that occurs when Java compiler is compiling our codes but it finds some codes which are lack of error checking or having unsafe operation. However, it's just an warning rather than error. It means that your codes will still run successfully and display the desired output.
Examples of Java uses unchecked or unsafe operations
public static void main(String[] args) {
ArrayList students = new ArrayList();
students.add("Alex");
students.add("Cindy");
students.add("Benjamin");
for(int i = 0; i < students.size(); i++){
System.out.println(students.get(i));
}
}
This is the output:
Note: C:\Users\MC\Documents\NetBeansProjects\LabViva\src\labviva\NewMain.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
compile-single:
run-single:
Alex
Cindy
Benjamin
Look, we've got the desired output, as we print each student in the ArrayList, students. However, you may also notice the warning: uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
Causes of Java warning: uses unchecked or unsafe operations
Basically, it occurs when we use raw types of collections rather than paramaterized types, Which is also known as generics of collections. This is due to the reason that specifying the raw types of collections in hazardous as it might produce unexpected error during runtime, such as ClassCastException. For example:
public static void main(String[] args) {
ArrayList numbers = new ArrayList();
numbers.add(1);
numbers.add(2);
numbers.add("Cindy");
for(int i = 0; i < numbers.size() - 1; i++){
System.out.println((int)numbers.get(i) + (int)numbers.get(i + 1));
}
}
This is the output:
Note: C:\Users\MC\Documents\NetBeansProjects\LabViva\src\labviva\NewMain.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
compile-single:
run-single:
3
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap')
Here, we're trying to cast the value, "Cindy" to an integer value for addition opearation, which is invalid and hazardous. This error happens because we're using the raw ArrayList! We accidentally insert a String value into the ArrayList of Integer type.
So now, how can we differentiate the raw collections and generic collections?
Examples:
ArrayList students = new ArrayList();
This is the raw types of ArrayList without any type specifier.
ArrayList students = new ArrayList();
The ArrayList, students has the type specifier, which is , but it doesn't include it at the end of the constructor.
Both of the examples above will render the compilation error: "Uses unchecked or unsafe operations" because the Java compiler refers to the ArrayList raw type rather than generic types.
This is the generic collections:
ArrayList students = new ArrayList();
or like this:
ArrayList students = new ArrayList<>();
After specifying the generic types, ArrayList at the front, we can substitute the parameterized type of construtor with empty diamond, <> as the compiler may recognize the generic data type and do the type inference automatically.
Solution to Java warning: uses unchecked or unsafe operations
The solution is pretty simple and straightforward. You should always use generic collections rather than raw collections! It's always the best to specify the data type of the collections so that the Java compiler can check across the collections to make sure it stores a list of values with same data type to avoid any unintentional error.
public static void main(String[] args) {
ArrayList students = new ArrayList<>();
students.add("Alex");
students.add("Cindy");
students.add("Benjamin");
for(int i = 0; i < students.size(); i++){
System.out.println(students.get(i));
}
}
This is the output:
Alex
Cindy
Benjamin
BUILD SUCCESSFUL (total time: 1 second)
You may notice that the compile warning: "Uses unchecked or unsafe operations" has gone.
After specifying the generic type, if you add a value with data type different from that generic type, you would get the compile error.
public static void main(String[] args) {
ArrayList students = new ArrayList<>();
students.add("Alex");
students.add("Cindy");
students.add(1);
for(int i = 0; i < students.size(); i++){
System.out.println(students.get(i));
}
}
This is the compile error:
incompatible types: int cannot be converted to String
This is because the value, 1 has Integer data type, which is incompatible to the generic type, of the collection.
If you want to know why and where the compile error happens, you can recompile your projects using the -Xlint:unchecked command.
For Apache Netbeans, go to Your Project -> Properties -> Compiling -> Additional Compilation Options, and paste -Xlint:unchecked. When you run the codes:
public static void main(String[] args) {
ArrayList students = new ArrayList();
students.add("Alex");
students.add("Cindy");
students.add("Benjamin");
for(int i = 0; i < students.size(); i++){
System.out.println(students.get(i));
}
}
This is the output:
C:\Users\MC\Documents\NetBeansProjects\LabViva\src\labviva\NewMain.java:21: warning: [unchecked] unchecked call to add(E) as a member of the raw type ArrayList
students.add("Alex");
where E is a type-variable:
E extends Object declared in class ArrayList
C:\Users\MC\Documents\NetBeansProjects\LabViva\src\labviva\NewMain.java:22: warning: [unchecked] unchecked call to add(E) as a member of the raw type ArrayList
students.add("Cindy");
where E is a type-variable:
E extends Object declared in class ArrayList
C:\Users\MC\Documents\NetBeansProjects\LabViva\src\labviva\NewMain.java:23: warning: [unchecked] unchecked call to add(E) as a member of the raw type ArrayList
students.add("Benjamin");
where E is a type-variable:
E extends Object declared in class ArrayList
3 warnings
compile-single:
run-single:
Alex
Cindy
Benjamin
BUILD SUCCESSFUL (total time: 1 second)
Then, you can notice what of your codes produce this compile warnings.
You can also use @SuppressWarnings("unchecked") to hide this warning. However, it's inadvisable because we should always use generic collections rather than raw collections. Hiding this warning will cause you to not realise when you're using raw collections.
@SuppressWarnings("unchecked")
public static void main(String[] args) {
ArrayList students = new ArrayList();
students.add("Alex");
students.add("Cindy");
students.add("Benjamin");
for(int i = 0; i < students.size(); i++){
System.out.println(students.get(i));
}
}
This is the output:
Alex
Cindy
Benjamin
BUILD SUCCESSFUL (total time: 1 second)
The compilation warning: "uses unchecked or unsafe operations" is now hidden rather than solved.
That's all about Java uses unchecked or unsafe operations and the way to solve it. Hope it helps, Thanks! :)