4

I have been working with SpringBatch and looking the sourcecode of the class

org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor<T>

And I have found this:

public void setNames(String[] names) {
    Assert.notNull(names, "Names must be non-null");
    this.names = Arrays.asList(names).toArray(new String[names.length]);
}
  • What is the purpose of converting an array into a list into an array again?
  • Why not use something like this:
public void setNames(String[] names) {
    Assert.notNull(names, "Names must be non-null");
    this.names = names; // Simpler and without conversions
}
  • Or this to create a new instance isolated:
public void setNames(String[] names) {
    Assert.notNull(names, "Names must be non-null");
    this.names = names.clone(); //Simpler and create a new instance
}

All answers all welcome.

Balbu
  • 56
  • 5
  • 3
    I cannot think of a specific reason not to use clone, but there are good reasons to copy the names. – Stephen C Jan 20 '20 at 10:02
  • 4
    This is just a not-very-efficient way to create a copy of array. `.clone()` will do the same, but likely in more performant way. Also, supplying a non-empty array in `toArray()` call is now considered a [bad practice](https://shipilev.net/blog/2016/arrays-wisdom-ancients/). You may submit an issue at https://github.com/spring-projects/spring-batch/issues – apangin Jan 20 '20 at 10:06
  • 1
    So the code wants to have an independent copy, that cannot be changed from the outside. Maybe the programmer did not remember `clone` or `Arrays.copyOf`. – Joop Eggen Jan 20 '20 at 10:07
  • 1
    Look up "defensive copying", it's the name of this technique. – Sergey Kalinichenko Jan 20 '20 at 10:10

1 Answers1

2

This is usually done to create a copy of the supplied array although it's easier to do with System.arraycopy().

The copied array is needed to make the receiving object immutable. Consider the following example without the copy being done:

String[] names = { "John", "Pat", "Willy" };
obj.setNames(names);
names[0] = "Nathan";
// at which point obj.names also has Nathan
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111