Why is Arrays.asList(…).toArray().getClass() giving different results in JDK 1.8 and 11?
up vote
16
down vote
favorite
Why does the following condition return true
with JDK 1.8.0_131, whereas it returns false
with JDK 11.0.1?
String.class == Arrays.asList("a", "b").toArray().getClass()
java java-11
add a comment |
up vote
16
down vote
favorite
Why does the following condition return true
with JDK 1.8.0_131, whereas it returns false
with JDK 11.0.1?
String.class == Arrays.asList("a", "b").toArray().getClass()
java java-11
add a comment |
up vote
16
down vote
favorite
up vote
16
down vote
favorite
Why does the following condition return true
with JDK 1.8.0_131, whereas it returns false
with JDK 11.0.1?
String.class == Arrays.asList("a", "b").toArray().getClass()
java java-11
Why does the following condition return true
with JDK 1.8.0_131, whereas it returns false
with JDK 11.0.1?
String.class == Arrays.asList("a", "b").toArray().getClass()
java java-11
java java-11
edited 49 mins ago
Boann
36.6k1287121
36.6k1287121
asked 4 hours ago
Felix
2567
2567
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
21
down vote
The List
type returned by asList
is Arrays$ArrayList
. The toArray
method in jdk 8 on that class is:
@Override
public Object toArray() {
return a.clone();
}
But in jdk 11 it is:
@Override
public Object toArray() {
return Arrays.copyOf(a, a.length, Object.class);
}
In both cases a String
is passed to asList
, but in the jdk 8 case it is cloned, which retains its array type (String
), and in jdk 11 it is copied using Arrays.copyOf
with the explicit new array type of Object
.
This difference means that in jdk 8 Arrays.asList("a", "b").toArray().getClass()
returns String
and in jdk 11 it returns Object
, so in jdk 11 your expression will evaluate to false
.
The reason for this change comes from JDK-6260652 with the motivation:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject
.
If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
So this change was made to fix the previous behaviour.
If this is a problem for you, the related release note offers this as a work-around:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T)
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String array = list.toArray(new String[0]);
add a comment |
up vote
5
down vote
I would say that this was a bug in JDK 8 and before that has been fixed.
List<T>.toArray()
was always declared as returning Object
(see JavaDoc) - that it did in effect return String
in a special case was a mistake.
add a comment |
up vote
0
down vote
There are couple of reasons here
1) It is a bug in jdk-8 where should return java.lang.Object
but it is not and it is fixed in jdk-11
@Override
public Object toArray() {
return a.clone();
}
2) ==
operator is always used for reference comparison, so java.lang.String
or java.lang.Object
are objects which are singleton and immutable loaded at the time of JVM starts
System.out.println(String.class.hashCode()); //2018699554
System.out.println(Arrays.asList("a", "b").toArray().getClass().hashCode()); //2018699554
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrongjava.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann
– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing twojava.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.
– Boann
50 mins ago
sorry you are right, my intention is to explain==
opeartor will always comapre references andjava.lang.Object
orjava.lang.String
objects are singleton and immutable and load at JVM starts @Boann
– Deadpool
45 mins ago
That==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the twoClass
objects were being compared via.equals
. Or simply runningSystem.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.
– Boann
35 mins ago
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
21
down vote
The List
type returned by asList
is Arrays$ArrayList
. The toArray
method in jdk 8 on that class is:
@Override
public Object toArray() {
return a.clone();
}
But in jdk 11 it is:
@Override
public Object toArray() {
return Arrays.copyOf(a, a.length, Object.class);
}
In both cases a String
is passed to asList
, but in the jdk 8 case it is cloned, which retains its array type (String
), and in jdk 11 it is copied using Arrays.copyOf
with the explicit new array type of Object
.
This difference means that in jdk 8 Arrays.asList("a", "b").toArray().getClass()
returns String
and in jdk 11 it returns Object
, so in jdk 11 your expression will evaluate to false
.
The reason for this change comes from JDK-6260652 with the motivation:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject
.
If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
So this change was made to fix the previous behaviour.
If this is a problem for you, the related release note offers this as a work-around:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T)
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String array = list.toArray(new String[0]);
add a comment |
up vote
21
down vote
The List
type returned by asList
is Arrays$ArrayList
. The toArray
method in jdk 8 on that class is:
@Override
public Object toArray() {
return a.clone();
}
But in jdk 11 it is:
@Override
public Object toArray() {
return Arrays.copyOf(a, a.length, Object.class);
}
In both cases a String
is passed to asList
, but in the jdk 8 case it is cloned, which retains its array type (String
), and in jdk 11 it is copied using Arrays.copyOf
with the explicit new array type of Object
.
This difference means that in jdk 8 Arrays.asList("a", "b").toArray().getClass()
returns String
and in jdk 11 it returns Object
, so in jdk 11 your expression will evaluate to false
.
The reason for this change comes from JDK-6260652 with the motivation:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject
.
If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
So this change was made to fix the previous behaviour.
If this is a problem for you, the related release note offers this as a work-around:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T)
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String array = list.toArray(new String[0]);
add a comment |
up vote
21
down vote
up vote
21
down vote
The List
type returned by asList
is Arrays$ArrayList
. The toArray
method in jdk 8 on that class is:
@Override
public Object toArray() {
return a.clone();
}
But in jdk 11 it is:
@Override
public Object toArray() {
return Arrays.copyOf(a, a.length, Object.class);
}
In both cases a String
is passed to asList
, but in the jdk 8 case it is cloned, which retains its array type (String
), and in jdk 11 it is copied using Arrays.copyOf
with the explicit new array type of Object
.
This difference means that in jdk 8 Arrays.asList("a", "b").toArray().getClass()
returns String
and in jdk 11 it returns Object
, so in jdk 11 your expression will evaluate to false
.
The reason for this change comes from JDK-6260652 with the motivation:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject
.
If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
So this change was made to fix the previous behaviour.
If this is a problem for you, the related release note offers this as a work-around:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T)
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String array = list.toArray(new String[0]);
The List
type returned by asList
is Arrays$ArrayList
. The toArray
method in jdk 8 on that class is:
@Override
public Object toArray() {
return a.clone();
}
But in jdk 11 it is:
@Override
public Object toArray() {
return Arrays.copyOf(a, a.length, Object.class);
}
In both cases a String
is passed to asList
, but in the jdk 8 case it is cloned, which retains its array type (String
), and in jdk 11 it is copied using Arrays.copyOf
with the explicit new array type of Object
.
This difference means that in jdk 8 Arrays.asList("a", "b").toArray().getClass()
returns String
and in jdk 11 it returns Object
, so in jdk 11 your expression will evaluate to false
.
The reason for this change comes from JDK-6260652 with the motivation:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject
.
If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
So this change was made to fix the previous behaviour.
If this is a problem for you, the related release note offers this as a work-around:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T)
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String array = list.toArray(new String[0]);
edited 27 mins ago
Dave Newton
139k18208253
139k18208253
answered 3 hours ago
Jorn Vernee
19.4k33156
19.4k33156
add a comment |
add a comment |
up vote
5
down vote
I would say that this was a bug in JDK 8 and before that has been fixed.
List<T>.toArray()
was always declared as returning Object
(see JavaDoc) - that it did in effect return String
in a special case was a mistake.
add a comment |
up vote
5
down vote
I would say that this was a bug in JDK 8 and before that has been fixed.
List<T>.toArray()
was always declared as returning Object
(see JavaDoc) - that it did in effect return String
in a special case was a mistake.
add a comment |
up vote
5
down vote
up vote
5
down vote
I would say that this was a bug in JDK 8 and before that has been fixed.
List<T>.toArray()
was always declared as returning Object
(see JavaDoc) - that it did in effect return String
in a special case was a mistake.
I would say that this was a bug in JDK 8 and before that has been fixed.
List<T>.toArray()
was always declared as returning Object
(see JavaDoc) - that it did in effect return String
in a special case was a mistake.
answered 3 hours ago
Thomas Kläger
5,8592717
5,8592717
add a comment |
add a comment |
up vote
0
down vote
There are couple of reasons here
1) It is a bug in jdk-8 where should return java.lang.Object
but it is not and it is fixed in jdk-11
@Override
public Object toArray() {
return a.clone();
}
2) ==
operator is always used for reference comparison, so java.lang.String
or java.lang.Object
are objects which are singleton and immutable loaded at the time of JVM starts
System.out.println(String.class.hashCode()); //2018699554
System.out.println(Arrays.asList("a", "b").toArray().getClass().hashCode()); //2018699554
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrongjava.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann
– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing twojava.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.
– Boann
50 mins ago
sorry you are right, my intention is to explain==
opeartor will always comapre references andjava.lang.Object
orjava.lang.String
objects are singleton and immutable and load at JVM starts @Boann
– Deadpool
45 mins ago
That==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the twoClass
objects were being compared via.equals
. Or simply runningSystem.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.
– Boann
35 mins ago
add a comment |
up vote
0
down vote
There are couple of reasons here
1) It is a bug in jdk-8 where should return java.lang.Object
but it is not and it is fixed in jdk-11
@Override
public Object toArray() {
return a.clone();
}
2) ==
operator is always used for reference comparison, so java.lang.String
or java.lang.Object
are objects which are singleton and immutable loaded at the time of JVM starts
System.out.println(String.class.hashCode()); //2018699554
System.out.println(Arrays.asList("a", "b").toArray().getClass().hashCode()); //2018699554
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrongjava.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann
– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing twojava.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.
– Boann
50 mins ago
sorry you are right, my intention is to explain==
opeartor will always comapre references andjava.lang.Object
orjava.lang.String
objects are singleton and immutable and load at JVM starts @Boann
– Deadpool
45 mins ago
That==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the twoClass
objects were being compared via.equals
. Or simply runningSystem.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.
– Boann
35 mins ago
add a comment |
up vote
0
down vote
up vote
0
down vote
There are couple of reasons here
1) It is a bug in jdk-8 where should return java.lang.Object
but it is not and it is fixed in jdk-11
@Override
public Object toArray() {
return a.clone();
}
2) ==
operator is always used for reference comparison, so java.lang.String
or java.lang.Object
are objects which are singleton and immutable loaded at the time of JVM starts
System.out.println(String.class.hashCode()); //2018699554
System.out.println(Arrays.asList("a", "b").toArray().getClass().hashCode()); //2018699554
There are couple of reasons here
1) It is a bug in jdk-8 where should return java.lang.Object
but it is not and it is fixed in jdk-11
@Override
public Object toArray() {
return a.clone();
}
2) ==
operator is always used for reference comparison, so java.lang.String
or java.lang.Object
are objects which are singleton and immutable loaded at the time of JVM starts
System.out.println(String.class.hashCode()); //2018699554
System.out.println(Arrays.asList("a", "b").toArray().getClass().hashCode()); //2018699554
edited 44 mins ago
answered 2 hours ago
Deadpool
3,2482324
3,2482324
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrongjava.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann
– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing twojava.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.
– Boann
50 mins ago
sorry you are right, my intention is to explain==
opeartor will always comapre references andjava.lang.Object
orjava.lang.String
objects are singleton and immutable and load at JVM starts @Boann
– Deadpool
45 mins ago
That==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the twoClass
objects were being compared via.equals
. Or simply runningSystem.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.
– Boann
35 mins ago
add a comment |
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrongjava.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann
– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing twojava.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.
– Boann
50 mins ago
sorry you are right, my intention is to explain==
opeartor will always comapre references andjava.lang.Object
orjava.lang.String
objects are singleton and immutable and load at JVM starts @Boann
– Deadpool
45 mins ago
That==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the twoClass
objects were being compared via.equals
. Or simply runningSystem.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.
– Boann
35 mins ago
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
String pools have nothing to do with what's going on here.
– Boann
1 hour ago
is that wrong
java.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann– Deadpool
1 hour ago
is that wrong
java.lang.String
is string object that created while JVM loading in object heap memory or String pool, is that wrong? String constants are stored in pool, objects are stored in heap @Boann– Deadpool
1 hour ago
Nothing in the question is comparing any strings; it's comparing two
java.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.– Boann
50 mins ago
Nothing in the question is comparing any strings; it's comparing two
java.lang.Class
objects. Its behavior would be the same even if there were no such thing as the string constant pool.– Boann
50 mins ago
sorry you are right, my intention is to explain
==
opeartor will always comapre references and java.lang.Object
or java.lang.String
objects are singleton and immutable and load at JVM starts @Boann– Deadpool
45 mins ago
sorry you are right, my intention is to explain
==
opeartor will always comapre references and java.lang.Object
or java.lang.String
objects are singleton and immutable and load at JVM starts @Boann– Deadpool
45 mins ago
That
==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the two Class
objects were being compared via .equals
. Or simply running System.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.– Boann
35 mins ago
That
==
compares object references is true, but misses the point of the question. The behavior of the code in the question would be exactly the same if the two Class
objects were being compared via .equals
. Or simply running System.out.println(Arrays.asList(1, 2, 3).toArray());
also illustrates the behavior change between JDK 8 and JDK 9+.– Boann
35 mins ago
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53696569%2fwhy-is-arrays-aslist-toarray-getclass-giving-different-results-in-jdk-1%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown