问题
I'm triying to understand method references and I don't know how with this "Book[]::new" it can create an array with the right number of elements.
Book[] arrayBook = stBooks.toArray(Book[]::new);
In order to create the array when I use the second and third option I have to specify a Functional Interface that Receive an Int and return a new Array.
But, in the first option I don't know where is the implementation and where you specify the number or elements that is going to have the array. I figure that it create a new array element for each Stream element but if I understand well you have to provide the implementation and "Book[]::new" doesn't have it.
Book book1 = new Book("ESDLA");
Book book2 = new Book("Harry Potter");
Stream<Book> stBooks = Stream.of(book1, book2);
1. Method References
Book[] arrayBook = stBooks.toArray(Book[]::new);
2. With Lambda Implementation
Book[] arrayBook1 = stBooks.toArray( (numElements) -> new Book[numElements] );
3. With Implementation
Book[] arrayBook2 = stBooks.toArray( new IntFunction<Book[]>() {
@Override
public Book[] apply(int numElements) {
return new Book[numElements];
}
});
回答1:
This is a special case in the language specification:
If the method reference expression has the form
ArrayType::new
, a single notional method is considered. The method has a single parameter of typeint
, returns theArrayType
, and has no throws clause. If n = 1, this is the only potentially applicable method; otherwise, there are no potentially applicable methods.
And also:
If the form is
Type[]^k :: new
(k ≥ 1), then the body of the invocation method has the same effect as an array creation expression of the formnew Type [ size ] []^k-1
, wheresize
is the invocation method's single parameter. (The notation[]^k
indicates a sequence of k bracket pairs.)
So the "implementation" that you want to find is hidden somewhere in the Java compiler, as it's all "compiler magic".
来源:https://stackoverflow.com/questions/65123253/how-knows-stream-toarraybooknew-how-many-elements-the-array-has-and-where