ClassCastException Double to Float

时间:2013-03-31 04:24:23

标签: java android casting

出于某种原因,这段代码抛出一个ClassCastException,告诉我我不能将Double转换为Float。例外情况来自下面的第一行代码。 mapData.speedsArrayList<Float>。 Double在哪里?

float spd = mapData.speeds.get(focusPointIndex);
spd = (spd * 3600/1609.34);

这是完整的堆栈跟踪:

03-31 01:00:51.008: E/AndroidRuntime(17778): FATAL EXCEPTION: main
03-31 01:00:51.008: E/AndroidRuntime(17778): java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float
03-31 01:00:51.008: E/AndroidRuntime(17778):    at net.taptools.android.trailtracker.ResultsMapViewingFragment$4.onMapLongClick(ResultsMapViewingFragment.java:224)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at com.google.android.gms.maps.GoogleMap$5.onMapLongClick(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at com.google.android.gms.internal.k$a.onTransact(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at android.os.Binder.transact(Binder.java:326)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at com.google.android.gms.maps.internal.IOnMapLongClickListener$Stub$Proxy.onMapLongClick(IOnMapLongClickListener.java:93)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.i.s.a(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.y.v.d(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.y.bf.onLongPress(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.d.v.onLongPress(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.d.h.c(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.d.h.c(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at maps.d.j.handleMessage(Unknown Source)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at android.os.Looper.loop(Looper.java:137)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at android.app.ActivityThread.main(ActivityThread.java:5059)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at java.lang.reflect.Method.invokeNative(Native Method)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at java.lang.reflect.Method.invoke(Method.java:511)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
03-31 01:00:51.008: E/AndroidRuntime(17778):    at dalvik.system.NativeStart.main(Native Method)

- 编辑 -

我想我已经找到导致错误的原因,但仍然不知道它为什么会发生,或者如何解决它。我正在使用JSON解析mapData对象,并且因为它包含许多不同类型的ArrayLists,所以我创建了一个方法,将JSONArray解析为指定类型的ArrayList。这是方法。

private <T> ArrayList<T> JSONArrayToList(JSONArray jsonArr){
        ArrayList<T> arrList = new ArrayList<T>();
        for(int i = 0; i<jsonArr.length(); i++){
            try {
                arrList.add((T)jsonArr.get(i));
            } catch (JSONException e){e.printStackTrace();}
        }
        return arrList;
    }

3 个答案:

答案 0 :(得分:3)

我猜你的代码实际上将spd声明为Float(而不是float)。我也猜测异常来自第二行。尝试将第二行更改为:

spd = (spd * 3600 / 1609.34f);

这会使右侧成为float而不是double。 Java中的浮点文字是double,除非它们以fF结尾。

如果我的猜测是准确的,那么异常是由Java将double - 值表达式自动装箱到Double然后尝试将其转换为Float而引起的。为了将其分配给变量spd

玩了一下之后,我发现我无法复制你的错误信息。你的代码甚至不会编译;编译器在第二行抱怨“错误:可能丢失精度”。所以现在我有另一个猜测:你已经压制了这个错误信息(或者将其设置为警告而不是错误而忽略它)。

答案 1 :(得分:1)

如果mapData.speeds确实被声明为ArrayList<Float>,则唯一可以获得类强制转换异常的方法就是禁止/忽略一些有关不安全转换的警告。 (在设置speed属性的代码或将值放入列表的代码中。)

将会发生类强制转换,因为您的代码实际上等同于此:

Float tmp = (Float) (mapData.speeds.get(focusPointIndex));
float spd = tmp.floatValue();

mapData.speeds.get的实际(已删除)签名为Object get(int)

通常情况下(即如果你没有禁止警告),编译器会告诉你是否做了 导致Double被添加到ArrayList<Float>的内容。但是,如果您忽略这些警告,则最终可以使用Double作为ArrayList<Float>。如果发生这种情况,当您将get的结果用作float时,您将获得一个类强制转换异常。

答案 2 :(得分:0)

3600/1609.34更改为3600f / 1609.34f

如果在代码中使用十进制数,则将其推断为double类型。在数字的末尾加上一个F来告诉编译器它是一个float而不是double。

为了获得最佳实践,请养成使用D或F(Double或Float)结束小数常量的习惯。 考虑到Java只是为了编写最简单的流程而输入你的大脑,看起来似乎有些过分。