diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md
index 9eac6d5a65..7831cce638 100644
--- a/docs/pages/release_notes.md
+++ b/docs/pages/release_notes.md
@@ -53,10 +53,25 @@ The command line version of PMD continues to use **scala 2.13**.
* The new Java Rule {% rule "java/codestyle/UnnecessaryCast" %} (`java-codestyle`)
finds casts that are unnecessary while accessing collection elements.
+
+#### Modified rules
+
+* The Java rule {% rule "java/codestyle/UseDiamondOperator" %} (`java-codestyle`) now by default
+ finds unnecessary usages of type parameters, which are nested, involve wildcards and are used
+ within a ternary operator. These usages are usually only unnecessary with Java8 and later, when
+ the type inference in Java has been improved.
+
+ In order to avoid false positives when checking Java7 only code, the rule has the new property
+ `java7Compatibility`, which is disabled by default. Settings this to "true" retains
+ the old rule behaviour.
+
+
### Fixed Issues
* c#
* [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work
+* java-codestyle
+ * [#2545](https://github.com/pmd/pmd/issues/2545): \[java] UseDiamondOperator false negatives
* java-design
* [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods
* scala
diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml
index 62a8c4c589..23469bb469 100644
--- a/pmd-java/src/main/resources/category/java/codestyle.xml
+++ b/pmd-java/src/main/resources/category/java/codestyle.xml
@@ -1673,6 +1673,11 @@ Use the diamond operator to let the type be inferred automatically. With the Dia
to avoid duplication of the type parameters.
Instead, the compiler is now able to infer the parameter types for constructor calls,
which makes the code also more readable.
+
+The diamond operator has been introduced with java 7. However, type inference has been improved further
+with java8, rendering more type parameters unnecessary. This is only possible with java8 and the resulting
+code won't compile with java7. If you use java7, make sure to enable `java7Compatibility` for this rule to avoid
+false positives.
3
@@ -1685,15 +1690,17 @@ which makes the code also more readable.
|
//StatementExpression[AssignmentOperator and PrimaryExpression/PrimaryPrefix[not(Expression)]]
)
-/Expression/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
+/(Expression | Expression[$java7Compatibility = false()]/ConditionalExpression | Expression[$java7Compatibility = false()]/ConditionalExpression/Expression)
+/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
/PrimaryPrefix
/AllocationExpression
[@AnonymousClass=false()]
- [ClassOrInterfaceType/TypeArguments[@Diamond=false() and not(TypeArgument//TypeArguments)]]
+ [ClassOrInterfaceType/TypeArguments[@Diamond=false() and not($java7Compatibility = true() and .//TypeArgument[@Wildcard=true()])]]
[not(ArrayDimsAndInits)]
]]>
+
Use Diamond
- 2
- 6,11
+ 3
+ 6,9,10
strings = new ArrayList();
List strings2 = new ArrayList<>();
List> strings3 = new ArrayList<>();
- // this is a known false negative, see at the bottom
List> strings4 = new ArrayList>>();
this.field = new ArrayList();
}
@@ -139,35 +138,43 @@ class Foo {
-
-
- (J7) Version sensitive tests
- 1
- 6
+
+ (J7) Version sensitive tests - avoid possible false positives on Java7
+ true
+ 0
> typeReference;
public void foo() {
// this should be positive in Java 8, negative in Java 7
+ // in java 7: no violation, in java 8 violation
+ typeReference = new WeakReference>(String.class);
// this is because in java 7, new WeakReference<>(String.class) types as WeakReference>
// which is incompatible with WeakReference>, whereas Java 8's type inference is better.
- typeReference = new WeakReference>(String.class);
+
+ // the following is the same:
+ // in java 7: no violation, in java 8 violation
Class> type = null;
- typeReference = new WeakReference>(type); // this should be positive on all versions
+ typeReference = new WeakReference>(type);
}
}
]]>
-
- (J8) Version sensitive tests
+
+ (J8) Version sensitive tests - known false negatives on Java8+
2
- 4,6
+ 6,8
> typeReference;
public void foo() {
@@ -175,6 +182,51 @@ public class Foo {
Class> type = null;
typeReference = new WeakReference>(type); // pos
}
+}
+ ]]>
+
+
+
+ False negative for nested type parameters (#2545)
+ true
+ 3
+ 7,8,17
+ > l = new ArrayList
+
+
+
+ (J8+) False negative for Java8+ and ternary operator (#2545)
+ 2
+ 7,7
+ l2;
+ l2 = true ? new ArrayList() : new ArrayList(); // FN twice for java8+, but for java7, this is ok!
+ }
}
]]>