Reputation: 1794
I've run into a strange problem that I'm not understanding. I am working on a Java program that uses the Steam API to get Dota 2 statistics.
for (int i = 0; i < MAX_REQUESTS; i++) {
competitiveMatches.addAll(getByStartTime(startTime));
System.out.println("Time: " + competitiveMatches.get(competitiveMatches.size() - 1).getStartTime());
startTime = competitiveMatches.get(competitiveMatches.size() - 1).getStartTime();
}
I am getting an error on the System.out.println(...)
line saying:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Long
which to me is not making any sense, I am requesting the last match in my List, and accessing its start_time
variable which is the method below. It works by looking through the JSON Map and getting the value at the position.
@Override
public long getStartTime() {
return (Long) jsonMap.get(KEY_START_TIME);
}
The full stack trace:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Long
at de.inkvine.dota2stats.domain.impl.MatchOverviewImpl.getStartTime(MatchOverviewImpl.java:48)
at Silicon.main(Silicon.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Where
MatchOverviewImpl.java:48
is the return of the getStartMethod()
Silicon.java:34
is the System.out.println()
lineAn example of a request, the match_id
, match_seq_num
, and start_time
are all stored as doubles e.g. 1.929962146E9
:
{
"match_id":1929981128,
"match_seq_num":1705354677,
"start_time":1447289804,
"lobby_type":8,
"radiant_team_id":0,
"dire_team_id":0,
"players":[
{
"account_id":82228820,
"player_slot":0,
"hero_id":19
},
{
"account_id":4294967295,
"player_slot":128,
"hero_id":14
}
]
}
Upvotes: 1
Views: 1256
Reputation: 4111
Double, Long, Float, Integer, Long, Short
are subclasses of Number, they are not primitives. You cannot cast between them!
Java uses autoboxing only between the primitive types and their corresponding object wrapper classes, but unfortunately it doesn't between Objects and primitives of different Number types eg long to Integer
. To help you on casting between different Number types, each Number object is equipped with byteValue(),doubleValue(),floatValue(),intValue(),longValue(),shortValue()
methods. So, you can actually call:
jsonMap.get(KEY_START_TIME).longValue();
or you could even use double-casting, taking advantage of autoboxing
(long)(double)jsonMap.get(KEY_START_TIME);
Upvotes: 1
Reputation: 13575
You are trying to convert a Double
to a long
via casting, which is not possible. You can convert the Double
to its long
counterpart by calling longValue
:
@Override
public long getStartTime() {
return jsonMap.get(KEY_START_TIME).longValue();
}
This is because in JSON, like JavaScript, all numbers are floating point numbers (well, the spec doesn't make any distinction), so it is likely that the JSON library you are using returns you Double
objects regardless of whether or not the number has a fractional part.
Upvotes: 1