A new helper method Arrays.asArray

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Jun 14 22:38:30 UTC 2016


----- Mail original -----

> De: "timo kinnunen" <timo.kinnunen at gmail.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "core-libs-dev" <core-libs-dev at openjdk.java.net>, "Louis Wasserman"
> <lowasser at google.com>
> Envoyé: Mardi 14 Juin 2016 23:39:19
> Objet: RE: A new helper method Arrays.asArray

> I think @SafeVarargs should be OK here since the array containing the varargs
> already exists before the method starts executing and so the annotation
> amounts to asserting that the passed-in vararg-array is just as safe during
> the execution of the method as it is after the method execution completes.

> In any case, I’m only adding it to my versions to silence a compiler warning.
> In a JDK version the API doc should nail down that the method executes
> indistinguishable from a method which simply returns the passed-in array and
> the JDK version can freely choose which annotations to have. I would
> actually prefer the JDK implementation to use @ForceInline or something like
> that instead which my versions can’t use. This would guarantee that there is
> no overhead in calling the method and that type-safety issues present, if
> any, will occur within the calling context. Which is where they would have
> been introduced.

Given the code of your method, it will be inlined because the implementation is trivial. 

And your code is unsafe because you can have a ClassCastException with no warning at a line where you see no cast,far away from where the bug lies, 
List<String> list1 = new ArrayList<>(); 
list1.add("hello"); 
List<Integer> list2 = new ArrayList<>(); 
list2.add(1); 

List<String>[] array = asArray(list1, null); 
List<?>[] array2 = array; 
array2[1] = list2; 

for(List<String> l: array) { 
System.out.println(l.get(0)); 
} 

A warning in Java means something goes wrong and the compiler and the VM can not help you, forget about @SuppressWarnings or @SafeVarargs and change your code if you are not writing a class of java.util or guava. 

cheers, 
Rémi 

> --
> Have a nice day,
> Timo

> Sent from Mail for Windows 10

> From: Remi Forax
> Sent: Tuesday, June 14, 2016 21:43
> To: timo kinnunen
> Cc: core-libs-dev ; Louis Wasserman
> Subject: Re: A new helper method Arrays.asArray

> Hi Timo,

> your implementation can not use @SafeVarargs because you leak the array (you
> return it) so you're code is not safe because you can not be sure that the
> resulting array will not be modified after the call to asArray.

> Louis, because you can not create an array of parametrized type in Java :)

> Here, the easy solution is to not create an array but a List,

> List<Comparator<Object>> list = List.of(sort0, sort1);

> or

> List<Comparator<Object>> list = Arrays.asList(sort0, sort1);

> depending if you want a mutable List (but with a fixed size) or an immutable
> one.

> cheers,

> Rémi

> ----- Mail original -----

> > De: "Louis Wasserman" <lowasser at google.com>

> > À: "timo kinnunen" <timo.kinnunen at gmail.com>, "core-libs-dev"
> > <core-libs-dev at openjdk.java.net>

> > Envoyé: Mardi 14 Juin 2016 19:47:23

> > Objet: Re: A new helper method Arrays.asArray

> >

> > Why would you not just write new Object[] {sort0, sort1, sort2, sort3}?

> >

> > On Tue, Jun 14, 2016, 10:35 AM <timo.kinnunen at gmail.com> wrote:

> >

> > >

> > > Hi,

> > >

> > > I have found that many times I need to write this simple helper method:

> > >

> > > public static @SafeVarargs <T> T[] asArray(T… ts) { return ts; }

> > >

> > >

> > > I usually need this when I have several implementations I’m comparing and

> > > I want to change the code for observing one of them to observing two or

> > > more of them in sequence. I feel that in this case switching from
> > > operating

> > > on one object to operating on an unknown List implementation (from

> > > Arrays.asList) is a too drastic change when all I need is put a for-loop

> > > around some code and iterate.

> > >

> > > The code for which I have to write this method is often some variation of

> > > something like this:

> > >

> > > Comparator<Object> sort1 = (x, y) -> (Integer) x - (Integer) y;

> > > Comparator<Object> sort0 = (x, y) -> (int) (Math.pow((Integer) x,

> > > 2.0) - Math.pow((Integer) y, 2.0));

> > >

> > > // Have to use a helper method here

> > > Comparator<Object>[] sorts = asArray(sort0, sort1, sort2, sort3);

> > >

> > >

> > > Please consider and add this simple method to Arrays.

> > >

> > >

> > >

> > > --

> > > Have a nice day,

> > > Timo

> > >

> > > Sent from Mail for Windows 10

> > >

> > >

> >


More information about the core-libs-dev mailing list