[ https://issues.apache.org/jira/browse/GROOVY-11629?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17947539#comment-17947539 ]
Oscar N commented on GROOVY-11629: ---------------------------------- I think you could support parameters, variables and field references when they're either marked as final or are never re-assigned (effectively-final). > Redundant null check on @NullChecked parameter when iterating on it > ------------------------------------------------------------------- > > Key: GROOVY-11629 > URL: https://issues.apache.org/jira/browse/GROOVY-11629 > Project: Groovy > Issue Type: Bug > Affects Versions: 5.0.0-alpha-12, 3.0.24, 4.0.26 > Reporter: Oscar N > Priority: Minor > > When looping over a method parameter whose method is annotated with > @NullCheck, an additional null check performed before iterating. Here's a > minimal example, demonstrating the numbers parameter being checked for null > twice: > {code:groovy} > import groovy.transform.CompileStatic > import groovy.transform.NullCheck > void main() { > listNumbers([1, 2, 3]) > } > @CompileStatic > @NullCheck > void listNumbers(List<Number> numbers) { > for (number in numbers) > println number > } > {code} > Decompiled Java representation of the bytecode: > {code:java} > public void listNumbers(List<Number> numbers) { > if (numbers == null) { > throw (Throwable)(new IllegalArgumentException("numbers cannot be > null")); > } else { > Iterator var10000 = numbers != null ? numbers.iterator() : null; > Object number = null; > Iterator var4 = var10000; > if (var4 != null) { > while(var4.hasNext()) { > number = var4.next(); > DefaultGroovyMethods.println(this, number); > Object var6 = null; > } > } > } > } > {code} > Bytecode: > {code:java} > // access flags 0x1 > // signature (Ljava/util/List<Ljava/lang/Number;>;)V > // declaration: void listNumbers(java.util.List<java.lang.Number>) > public listNumbers(Ljava/util/List;)V > L0 > ALOAD 1 > IFNONNULL L1 > ICONST_1 > GOTO L2 > L1 > ICONST_0 > L2 > IFEQ L3 > NEW java/lang/IllegalArgumentException > DUP > LDC "numbers cannot be null" > INVOKESPECIAL java/lang/IllegalArgumentException.<init> > (Ljava/lang/String;)V > CHECKCAST java/lang/Throwable > ATHROW > L3 > LINENUMBER 11 L3 > ALOAD 1 > DUP > ASTORE 2 > IFNULL L4 > ALOAD 2 > INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator; (itf) > GOTO L5 > L4 > ACONST_NULL > L5 > ACONST_NULL > ASTORE 3 > L6 > ASTORE 4 > ALOAD 4 > IFNULL L7 > L8 > ALOAD 4 > INVOKEINTERFACE java/util/Iterator.hasNext ()Z (itf) > IFEQ L7 > ALOAD 4 > INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object; (itf) > ASTORE 3 > L9 > LINENUMBER 12 L9 > ALOAD 0 > ALOAD 3 > INVOKESTATIC org/codehaus/groovy/runtime/DefaultGroovyMethods.println > (Ljava/lang/Object;Ljava/lang/Object;)V > ACONST_NULL > POP > GOTO L8 > L7 > LINENUMBER 13 L7 > RETURN > LOCALVARIABLE this LRedundantNullCheck; L0 L7 0 > LOCALVARIABLE numbers Ljava/util/List; L0 L7 1 > LOCALVARIABLE number Ljava/lang/Object; L6 L7 3 > MAXSTACK = 3 > MAXLOCALS = 5 > {code} > Note that this also happens in CompileDynamic mode. -- This message was sent by Atlassian Jira (v8.20.10#820010)