type safe array slice

A

Antony Sequeira

Hi

I wanted to make a type safe array slice method (at least for single
dimension arrays)
Here is what I have

public static <T> T [] arraySlice(T [] src, int offset, int length) {
int [] dim = new int [1];
dim[0] = length;
T[] dst;
dst = (T [])
java.lang.reflect.Array.newInstance(src.getClass().getComponentType() ,
dim );
System.arraycopy(src,offset,dst,0,length);
return dst;
}

This has two problems
1. Eclipse gives a warning for the type cast (T []) , saying
Type safety: The cast from Object to T[] is actually checking against
the erased type Object[]
2. this does not work for array of primitives such as int []

I am assuming this does provide type safe array slicing for single
dimension arrays of non primitives.

My questions :
Is the above a reasonable thing to do ?
Are there better solutions ?
Do you see any other issues with the above code ?

Thanks,
-Antony Sequeira
(I originally posted this to comp.lang.java, but did not get much info)
 
R

Roedy Green

I wanted to make a type safe array slice method (at least for single
dimension arrays)

have a look inside ArrayList to see how they handled these problems.
 
T

Thomas Hawtin

Antony said:
I wanted to make a type safe array slice method (at least for single
dimension arrays)
Here is what I have

public static <T> T [] arraySlice(T [] src, int offset, int length) {
int [] dim = new int [1];
dim[0] = length;
T[] dst;
dst = (T [])
java.lang.reflect.Array.newInstance(src.getClass().getComponentType() ,
dim );
System.arraycopy(src,offset,dst,0,length);
return dst;
}

This has two problems
1. Eclipse gives a warning for the type cast (T []) , saying
Type safety: The cast from Object to T[] is actually checking against
the erased type Object[]
2. this does not work for array of primitives such as int []

Yes, it will do that. If you passed int.class, which has type
Class<Integer> to Array.newInstance, then casting the result to
Integer[] or even Object[] would fail.

If you want to handle primitive types as well, then you'd need to
replace T[] with T. Much the same as System.arraycopy does.

From 1.6, you should be able to use Arrays.copyOfRange.
(I originally posted this to comp.lang.java, but did not get much info)

Probably because that newsgroup should have been deleted many years ago.

Tom Hawtin
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message

Antony Sequeira schreef:
Hi

I wanted to make a type safe array slice method (at least for single
dimension arrays)
Here is what I have

public static <T> T [] arraySlice(T [] src, int offset, int length) {
int [] dim = new int [1];
dim[0] = length;
T[] dst;
dst = (T [])
java.lang.reflect.Array.newInstance(src.getClass().getComponentType() ,
dim );
System.arraycopy(src,offset,dst,0,length);
return dst;
}

This has two problems
1. Eclipse gives a warning for the type cast (T []) , saying
Type safety: The cast from Object to T[] is actually checking against
the erased type Object[]
2. this does not work for array of primitives such as int []

I am assuming this does provide type safe array slicing for single
dimension arrays of non primitives.

My questions :
Is the above a reasonable thing to do ?
Are there better solutions ?
Do you see any other issues with the above code ?

I don't see any point in using the dim int array, when you can just use
length. You need a one-dimensional array anyway.

A trick is to pass the type as a parameter to the method.

@SuppressWarnings("unchecked")
public static <T> T [] arraySlice(T [] src, int offset, int
length, Class<T> type) {
T[] dst = (T []) java.lang.reflect.Array.newInstance(type, length);
System.arraycopy(src,offset,dst,0,length);
return dst;
}

-> You can't get rid of the warning except with
@SuppressWarnings("unchecked").
-> This still does not work with basic types.

See
http://www.angelikalanger.com/Gener...w do I generically create objects and arrays?
or http://tinyurl.com/lef99 for a more thorough explanation.

HTH, H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFEJ7ffe+7xMGD3itQRAi2zAJ95ihx91O5wocZKYAi2wrCXMz30VwCfeUTj
XTdTdUC/GlGANOoC4Cm4aZU=
=YS9p
-----END PGP SIGNATURE-----
 
T

Thomas Hawtin

Hendrik said:
A trick is to pass the type as a parameter to the method.

@SuppressWarnings("unchecked")
public static <T> T [] arraySlice(T [] src, int offset, int
length, Class<T> type) {
T[] dst = (T []) java.lang.reflect.Array.newInstance(type, length);
System.arraycopy(src,offset,dst,0,length);
return dst;
}

-> You can't get rid of the warning except with
@SuppressWarnings("unchecked").

You can if you pass the type of the array, instead of the component type:

public static <T> T[] copyOfRange(
T[] src, int offset, int length, Class<T[]> arrayClass
) {
T[] dst = arrayClass.cast(java.lang.reflect.Array.newInstance(
arrayClass.getComponentType(), length
));
System.arraycopy(src, offset, dst, 0, length);
return dst;
}

Unfortunately, there isn't a particularly nice way from getting from
component type to array type. Again the problem is that the type of an
array of int is not Class<Integer[]>.

Tom Hawtin
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message

Thomas Hawtin schreef:
Hendrik said:
A trick is to pass the type as a parameter to the method.

@SuppressWarnings("unchecked")
public static <T> T [] arraySlice(T [] src, int offset, int
length, Class<T> type) {
T[] dst = (T []) java.lang.reflect.Array.newInstance(type,
length);
System.arraycopy(src,offset,dst,0,length);
return dst;
}

-> You can't get rid of the warning except with
@SuppressWarnings("unchecked").

You can if you pass the type of the array, instead of the component type:

<snip>

Interesting, thanks.

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFEKQtYe+7xMGD3itQRAkL9AKCCAadmqfFlSYFVjXDhe+R8WGPb8ACfWpvK
xhH3woS76VtvkbbRUB4Vmls=
=DV1U
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top