ClassCastException Double 到 Float

问题描述 投票:0回答:4

出于某种原因,这段代码抛出了一个

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;
    }
java android casting
4个回答
4
投票

我猜测您的代码实际上将

spd
声明为
Float
(而不是
float
)。我还猜测例外是来自第二行。尝试将第二行更改为:

spd = (spd * 3600 / 1609.34f);

这将使右侧成为

float
而不是
double
。 Java 中的浮点文字是
double
,除非它们以
f
F
结尾。

如果我的猜测是准确的,则异常是由于 Java 将

double
值表达式自动装箱到
Double
,然后尝试将其转换为
Float
以将其分配给变量
spd
引起的。

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


2
投票

如果

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
时,您将收到类转换异常。
    


0
投票
3600/1609.34

更改为

3600f / 1609.34f

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

为了获得最佳实践,请养成始终以 D 或 F(双精度型或浮点型)结尾十进制常量的习惯。 考虑到 Java 让你绞尽脑汁只为了写出最简单的流程,这看起来似乎并不算大材小用。


0
投票

TL:博士;这是一个简单的类型转换问题。

让我们首先简要查看一下编辑中添加的代码示例,之前的响应没有对此做出反应。这个标题有点问题:

<T> ArrayList<T> JSONArrayToList(JSONArray jsonArr);

它是一个泛型方法,但它没有泛型参数。因此,类型信息的唯一来源是调用本身:基本上,类型信息仅来自旁观者的眼睛。

这意味着当尝试

arrList.add((T)jsonArr.get(i))

时,将从 JSON 数组的第

i
元素中选取一个元素,然后将其类型转换为从调用中推断出的任何类型。
Java 具有相当好的类型安全性,与 JavaScript 等语言相比,它动态转换类型的方法并不那么自由。由于 JSON 明显包含 

Double

并且该方法的结果被添加到

List<Float>
,因此尝试强制转换失败并完成。
为缺乏经验的开发人员提供强类型语言和 JSON。会出什么问题吗?

© www.soinside.com 2019 - 2024. All rights reserved.