2

出于某种原因,这段代码抛出了一个ClassCastException,告诉我我不能将 Double 转换为 Float。异常来自下面的第一行代码。mapData.speeds是一个ArrayList<Float>。双子在哪里?

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 对象,并且因为它包含许多各种类型的 ArrayList,我创建了一个将 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;
    }
4

3 回答 3

3

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

spd = (spd * 3600 / 1609.34f);

这将使右侧 afloat而不是 a double。Java 中的浮点文字double除非以for结尾F

如果我的猜测是准确的,那么异常是由 Java 将double-valued 表达式自动装箱到 aDouble然后尝试将其强制转换为 aFloat以便将其分配给 variable 引起的spd

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

于 2013-03-31T04:29:12.290 回答
2

如果mapData.speeds真的被声明为,ArrayList<Float>那么获得类转换异常的唯一方法是,如果您抑制/忽略了一些关于不安全转换的警告。(在设置 speed属性的代码或将值放入列表的代码中。)

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

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

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

通常(即,如果您不禁止警告)编译器会告诉您是否做了导致 aDouble被添加到ArrayList<Float>. 但是,如果您忽略这些警告,您最终Double可能会得到一个应该是ArrayList<Float>. get如果发生这种情况,当您使用as的结果时,您将得到一个类强制转换异常float

于 2013-03-31T04:30:33.147 回答
0

更改3600/1609.343600f / 1609.34f

如果您在代码中使用十进制数,它将被推断为双精度类型。在数字末尾包含 F 以告诉编译器它是浮点数而不是双精度数。

为获得最佳实践,请养成始终以 D 或 F(Double 或 Float)结尾的十进制常量的习惯。考虑到 Java 让您只为编写最简单的流程而绞尽脑汁,这似乎并不过分。

于 2013-03-31T04:59:36.967 回答