> On 8 Sep 2016, at 08:20, Patrick Reinhart <[email protected]> wrote:
>> And one more thing. Because we have now only one method to get a
>> stream I think the constant RESOURCE_CHARACTERISTICS should be defined
>> inside the #resources()-method. It is not needed to define it as a
>> static final field.
>
> The reason is to have the computation of the characteristics only at compile
> time not on each method call.
>
It’s ok, since the characteristics are constant the java compiler is free to
constant fold and compute results and use that instead in the byte code (which
is why for independent compilation it is dangerous to change the values of
static final fields of certain types, such as stuff that can be represented
directly in the constant pool or byte code).
So there is no need to increase the static size of the ClassLoader class with a
new static final field, although it probably makes little difference in this
case.
Paul.
[*]
Compile the following class and then view the byte code of the class file using
javap. You will not observe any getstatic instructions. Instead you will see
stuff like:
sipush 1280
that is the result of Spliterator.IMMUTABLE | Spliterator.NONNULL. Also notice
that the invoke dynamic for the Supplier<String> lambda is de-surgared into a
method that accepts an int parameter corresponding to the characteristics.
Arguably javac could be smarter here and fold the constant into the lambda
itself to avoid an additional parameter.
public class Statics {
public static void main(String[] args) {
usage(Spliterator.IMMUTABLE | Spliterator.NONNULL);
usage(Spliterator.IMMUTABLE | Spliterator.NONNULL);
create("FOO");
}
static Stream<String> create(String name) {
int cs = Spliterator.IMMUTABLE | Spliterator.NONNULL;
Supplier<Spliterator<String>> ss = () -> {
Iterator<String> i = List.of(name).iterator();
return Spliterators.spliteratorUnknownSize(i, cs);
};
return StreamSupport.stream(ss, cs, false);
}
static void usage(int cs) {}
}