Java 为什么我会得到这个ClassCastException?

Java 为什么我会得到这个ClassCastException?,java,casting,Java,Casting,我有两个非常简单的类,一个扩展了另一个: public class LocationType implements Parcelable { protected int locid = -1; protected String desc = ""; protected String dir = ""; protected double lat = -1000; protected double lng = -1000; pub

我有两个非常简单的类,一个扩展了另一个:

public class LocationType implements Parcelable {
    protected int    locid = -1;
    protected String desc  = "";
    protected String dir   = "";
    protected double lat   = -1000;
    protected double lng   = -1000;

    public LocationType() {}

    public int getLocid() {
        return locid;
    }

    public void setLocid(int value) {
        this.locid = value;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String value) {
        this.desc = value;
    }

    public String getDir() {
        return dir;
    }

    public void setDir(String value) {
        this.dir = value;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double value) {
        this.lat = value;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double value) {
        this.lng = value;
    }



    // **********************************************
    //  for implementing Parcelable
    // **********************************************

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt   (locid);
        dest.writeString(desc );
        dest.writeString(dir  );
        dest.writeDouble(lat  );
        dest.writeDouble(lng  );
    }

    public static final Parcelable.Creator<LocationType> CREATOR = new Parcelable.Creator<LocationType>() {
        public LocationType createFromParcel(Parcel in) {
            return new LocationType(in);
        }

        public LocationType[] newArray(int size) {
            return new LocationType[size];
        }
    };

    private LocationType(Parcel dest) {
        locid = dest.readInt   ();
        desc  = dest.readString();
        dir   = dest.readString();
        lat   = dest.readDouble();
        lng   = dest.readDouble();
    }
}
public类LocationType实现可包裹{
受保护的int locid=-1;
受保护字符串desc=“”;
受保护字符串dir=“”;
受保护双lat=-1000;
保护双液化天然气=-1000;
公共位置类型(){}
public int getLocid(){
返回locid;
}
公共void setLocid(int值){
this.locid=值;
}
公共字符串getDesc(){
返回描述;
}
公共void setDesc(字符串值){
this.desc=值;
}
公共字符串getDir(){
返回目录;
}
公共void setDir(字符串值){
this.dir=值;
}
公共双getLat(){
返回lat;
}
公共void setLat(双值){
this.lat=值;
}
公共双getLng(){
返回液化天然气;
}
公共无效设置(双倍值){
这1.lng=价值;
}
// **********************************************
//用于实现包裹
// **********************************************
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包裹(包裹目的地,内部标志){
目的地写入(locid);
目的地记录(说明);
目的地登记(直接);
目标可写双工(lat);
目的地可写资产(lng);
}
public static final Parcelable.Creator=新建Parcelable.Creator(){
公共位置类型createFromParcel(中的地块){
返回新的LocationType(在中);
}
公共位置类型[]新数组(整数大小){
返回新的LocationType[大小];
}
};
专用位置类型(地块目的地){
locid=dest.readInt();
desc=dest.readString();
dir=dest.readString();
lat=dest.readDouble();
lng=dest.readDouble();
}
}
以及:

公共类MyLocationType扩展了LocationType{

private ArrayList。这是为什么?

因为
LocationType
是超类;它不能强制转换为子类

进一步解释一下:您只能转换继承树,也就是说,对象只能转换为它创建时的类类型、它的任何超类或它实现的任何接口。因此,
字符串
可以转换为
字符串
对象
;可以转换
哈希映射
作为
HashMap
AbstractMap
Map
,或
对象

在您的情况下,
MyLocationType
可以是
MyLocationType
LocationType
(或
对象
),但反过来就不行了


这是因为
LocationType
不是
MyLocationType
的一个实例,它是它的父对象。例如,如果您将新方法添加到
MyLocationType
而不是
LocationType
中,然后将
LocationType
强制转换为
MyLocationType
,会出现什么情况如果调用了基本
位置类型中不存在的这些新方法,将发生ect


MyLocationType
LocationType
但是
LocationType
不是
MyLocationType
,因为
MyLocationType
属于类型
LocationType
,可以强制转换为一个,但是
LocationType
不是
MyLocationType
,因此不能强制转换为一个

因为您试图区分大小写的引用不是MyLocationType的实例

这个例子总是帮助我思考发生了什么

  Object o = new Object();

  String s = ( String ) o;
虽然字符串继承自对象,但这并不意味着每个对象都是字符串(或者在本例中,“casted”对象是字符串)

几乎从来都不需要明确地向下扔树,而向上扔树是有风险的:

public void doThis(LocationType lt) {
   MyLocationType myLt = (MyLocationType)lt; // DANGEROUS
}
只有在使用特定的 签名,然后您应该检查:

@Override
public void doThis(LocationType lt) {
   if (lt instanceof MyLocationType) {
     MyLocationType myLt = (MyLocationType)lt; 
   } else {
     // A LocationType but not MyLocationType
     doSomethingElse(lt);
   }
}
public void doThis(LocationType lt) {
   MyLocationType myLt = (MyLocationType)lt; // DANGEROUS
}
@Override
public void doThis(LocationType lt) {
   if (lt instanceof MyLocationType) {
     MyLocationType myLt = (MyLocationType)lt; 
   } else {
     // A LocationType but not MyLocationType
     doSomethingElse(lt);
   }
}