Java 具有空白类型的Android ClassCastException
我得到了一个奇怪的行为,我想我更多的是寻找一个解释而不是一个解决方案(虽然解决方案也是受欢迎的!) 代码如下:Java 具有空白类型的Android ClassCastException,java,android,exception,classcastexception,android-package-managers,Java,Android,Exception,Classcastexception,Android Package Managers,我得到了一个奇怪的行为,我想我更多的是寻找一个解释而不是一个解决方案(虽然解决方案也是受欢迎的!) 代码如下: PackageManager pm = context.getPackageManager(); List<PackageInfo> pkgList = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); if (pkgList == null) return null; for (Pac
PackageManager pm = context.getPackageManager();
List<PackageInfo> pkgList = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
if (pkgList == null)
return null;
for (PackageInfo pkgInfo : pkgList) {
ApplicationInfo appInfo = pkgInfo.applicationInfo;
// do some stuff, doesn't modify pkgInfo or appInfo or pkgList
}
奇怪的是,ClassCastException
通常看起来像(AFAIK):
java.lang.ClassCastException:foo.bar.ClassA不能强制转换为foo.bar.ClassB
然而,我看到的错误是第一部分显示为空白
我决定做一点研究,读到一些类似的东西,如果返回列表的函数在内部铸造了错误的对象列表并返回了它或其他东西,可能会发生这种情况。于是我看了看:
因此,项目是从PackageInfo.CREATOR.createFromParcel()
创建的
最后是PackageInfo
public static final Parcelable.Creator<PackageInfo> CREATOR
= new Parcelable.Creator<PackageInfo>() {
public PackageInfo createFromParcel(Parcel source) {
return new PackageInfo(source);
}
public PackageInfo[] newArray(int size) {
return new PackageInfo[size];
}
};
公共静态最终包裹。创建者
=新的Parcelable.Creator(){
公共包信息createFromParcel(包源){
返回新的PackageInfo(源);
}
公共PackageInfo[]新数组(整数大小){
返回新的PackageInfo[大小];
}
};
看来一切都很好。它正在创建一个PackageInfo
类型的ParceledListSlice
,因此在populateList
中,它正在创建一个PackageInfo
项,并将其放入PackageInfo
的列表中,这是返回的列表。我觉得所有类型/类别都很好
所以我的问题,
上述ClassCastException将如何发生李>
为什么会显示错误消息的“空白”类型李>
可能的解决办法是什么李>
我想把列表作为对象的列表
并检查“instanceof
”,但我认为这也行不通,因为它可能会说
ClassCastException:无法转换为“java.lang.Object”或其他内容
如果您能就如何实现这一点提供任何见解和解释,我们将不胜感激
Dalvik/JVM只是一团糟吗
内存是否已损坏
我只能胡乱猜测=)如果你确定你的ClassCastException
正好在这一行
for (PackageInfo pkgInfo : pkgList)
当一个原因在后面时,不知何故,pkgList
包含一个notPackageInfo
class的值。我假设这是NULL
value。这就是为什么在ClassCast错误消息中看不到它的原因,因为NULL对象的className
只是空字符串
现在,如何解决这个问题-使用循环手册。对于每个
循环,在引擎盖下使用迭代器
,因此您无法控制每次迭代中的类强制转换。但是如果您使用这样的代码:
for (int i = 0; i < pkgList.length; i++) {
Object pkgInfoObj = pkgList.get(i);
if (pkgInfoObj instanceof PackageInfo) {
PackageInfo pkgInfo = (PackageInfo) pkgInfoObj;
ApplicationInfo appInfo = pkgInfo.applicationInfo;
// do some stuff, doesn't modify pkgInfo or appInfo or pkgList
}
}
for(int i=0;i
你将能够控制类铸造
此外,您还可以捕获ClassCastException
并跳过此循环步骤进入下一步。这似乎是Android本身的问题。我发现一些针对Android的错误报告显示了类似的行为:
我还看到了26644期中提到的不兼容ClassChangeError。我唯一的猜测是,这些看似不可能的异常/错误是由于一些奇怪的内存损坏或dalvik/jvm问题造成的。代码本身似乎没有任何问题。如果其他人有更好的解释,请随意插入=) 如果你试图手动遍历列表并打印出每个项目的类型会怎么样?@NathanVillaescusa这是来自客户设备的日志,所以我不能这么做。它也不是100%可复制的。而且,我认为我不能循环遍历每个项目并打印出类型,因为我尝试获取项目的那一刻,它可能会抛出一个Clas不管怎样,我想是sCastException。我在想一个传统的for循环
,循环到pkgList
的长度。这会告诉你列表中的一些项目是否属于类PackageInfo
。我猜你的意思是做一个for(int I=0;Ipublic static final Parcelable.Creator<PackageInfo> CREATOR
= new Parcelable.Creator<PackageInfo>() {
public PackageInfo createFromParcel(Parcel source) {
return new PackageInfo(source);
}
public PackageInfo[] newArray(int size) {
return new PackageInfo[size];
}
};
for (PackageInfo pkgInfo : pkgList)
for (int i = 0; i < pkgList.length; i++) {
Object pkgInfoObj = pkgList.get(i);
if (pkgInfoObj instanceof PackageInfo) {
PackageInfo pkgInfo = (PackageInfo) pkgInfoObj;
ApplicationInfo appInfo = pkgInfo.applicationInfo;
// do some stuff, doesn't modify pkgInfo or appInfo or pkgList
}
}