Modify rule S3740: Migrate to LaYC format (#3191)

This commit is contained in:
Sylvain Kuchen 2023-10-04 10:01:40 +02:00 committed by GitHub
parent 3d55ef2283
commit 31d9a8ce3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,25 +1,67 @@
Generic types should not be used raw (without type parameters).
To fix this issue, add the type parameters.
== Why is this an issue?
Generic types shouldn't be used raw (without type parameters) in variable declarations or return values. Doing so bypasses generic type checking, and defers the catch of unsafe code to runtime.
A generic type is a generic class or interface that is parameterized over types.
For example, `java.util.List` has one type parameter: the type of its elements.
When generic types are used raw (without type parameters), the compiler is not able to do generic type checking.
For this reason, it is sometimes necessary to cast objects and defer type-checking to runtime.
=== Noncompliant code example
=== What is the potential impact?
[source,java]
When a cast fails, a `ClassCastException` is thrown and the program most likely crashes.
Therefore, this issue might impact the availability and reliability of your application.
== How to fix it
You should add type parameters.
In the case of collections, the type parameter(s) should correspond to the type of elements that the list is intended to store.
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
List myList; // Noncompliant
Set mySet; // Noncompliant
List integers = new ArrayList<>();
// It is possible to add a string to a list that is supposed to be integers only
integers.add("Hello World!");
Integer a = (Integer) integers.get(0); // ClassCastException!
----
==== Compliant solution
=== Compliant solution
[source,java]
[source,java,diff-id=1,diff-type=compliant]
----
List<String> myList;
Set<? extends Number> mySet;
List<Integer> integers = new ArrayList<>();
// The program does not compile anymore with this mistake:
// integers.add("Hello World!");
integers.add(42);
Integer a = integers.get(0); // No need to cast anymore.
----
=== How does this work?
In the noncompliant example, `List` is used as a raw type.
Even though the list stores integers, the compiler will type its elements as `Object`,
To use an element of the list as an integer, it needs to be cast first.
But elements are not garanteed to be integers.
In this case, a `String` is erroneously appended to the list, causing the cast to `Integer` to fail.
When the type parameter is specified, this bug is detected by the compiler during type-checking.
The cast is also unncessary in this case.
== Resources
=== Documentation
* https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html[Raw types] in the Java Tutorial.
ifdef::env-github,rspecator-view[]