diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java index 58af4a874d..18e5a418c2 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -712,10 +712,11 @@ public class Indexer extends SpelNodeImpl { } TypeDescriptor elementType = this.collectionEntryDescriptor.getElementTypeDescriptor(); try { - Constructor ctor = getConstructor(elementType.getType()); + Constructor ctor = getDefaultConstructor(elementType.getType()); int newElements = this.index - this.collection.size(); while (newElements >= 0) { - this.collection.add(ctor == null ? null : ctor.newInstance()); + // Insert a null value if the element type does not have a default constructor. + this.collection.add(ctor != null ? ctor.newInstance() : null); newElements--; } } @@ -725,7 +726,7 @@ public class Indexer extends SpelNodeImpl { } } - Constructor getConstructor(Class type) { + private Constructor getDefaultConstructor(Class type) { try { return ReflectionUtils.accessibleConstructor(type); } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java index 9d496cb711..922ec4a51a 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -203,22 +203,21 @@ public class IndexingTests { public List decimals; @Test - public void autoGrowWithoutDefaultConstructor() { + public void autoGrowListOfElementsWithoutDefaultConstructor() { this.decimals = new ArrayList<>(); SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); parser.parseExpression("decimals[0]").setValue(this, "123.4"); - assertThat(decimals.get(0)).isEqualTo(BigDecimal.valueOf(123.4)); + assertThat(decimals).containsExactly(BigDecimal.valueOf(123.4)); } @Test - public void indexIntoPropertyContainingNullList() { + public void indexIntoPropertyContainingListContainingNullElement() { this.decimals = new ArrayList<>(); this.decimals.add(null); this.decimals.add(BigDecimal.ONE); SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); parser.parseExpression("decimals[0]").setValue(this, "9876.5"); - assertThat(decimals.get(0)).isEqualTo(BigDecimal.valueOf(9876.5)); - assertThat(decimals.get(1)).isEqualTo(BigDecimal.ONE); + assertThat(decimals).containsExactly(BigDecimal.valueOf(9876.5), BigDecimal.ONE); } @Test diff --git a/src/docs/asciidoc/core/core-expressions.adoc b/src/docs/asciidoc/core/core-expressions.adoc index c88f9a95cf..53723fbc7e 100644 --- a/src/docs/asciidoc/core/core-expressions.adoc +++ b/src/docs/asciidoc/core/core-expressions.adoc @@ -332,19 +332,20 @@ being placed in it. The following example shows how to do so: [[expressions-parser-configuration]] === Parser Configuration -It is possible to configure the SpEL expression parser by using a parser configuration object -(`org.springframework.expression.spel.SpelParserConfiguration`). The configuration +It is possible to configure the SpEL expression parser by using a parser configuration +object (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration object controls the behavior of some of the expression components. For example, if you -index into an array or collection and the element at the specified index is `null`, -you can automatically create the element. This is useful when using expressions made up of a -chain of property references. If you index into an array or list -and specifying an index that is beyond the end of the current size of the array or -list, you can automatically grow the array or list to accommodate that index. In order to add -an element at the specified index, SpEL will try to create the element using a default -constructor before setting the specified value. If the element type does not have a default -constructor, `null` will be added. Note if there is no built-in or custom converter, that knows -how to set the value, `null` will remain in the array or list at the specified index. -The following example demonstrates how to automatically grow the list: +index into an array or collection and the element at the specified index is `null`, SpEL +can automatically create the element. This is useful when using expressions made up of a +chain of property references. If you index into an array or list and specify an index +that is beyond the end of the current size of the array or list, SpEL can automatically +grow the array or list to accommodate that index. In order to add an element at the +specified index, SpEL will try to create the element using the element type's default +constructor before setting the specified value. If the element type does not have a +default constructor, `null` will be added to the array or list. If there is no built-in +or custom converter that knows how to set the value, `null` will remain in the array or +list at the specified index. The following example demonstrates how to automatically grow +the list: [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java