我在理解如何创建子类的构造函数时遇到了一些问题,该构造函数扩展了Parent类。这是我正在使用的代码:
父类构造函数:
public RPCPacket( int apacketId,
RPCPacketType apacketType,
RPCOperationType aoperationType,
String tmpPacket_objectOid,
int aobjectId,
int adataSize,
String tmpPacket_dataHash,
RPCPacketDataType adataType,
byte[] apacketData){
RPCPacket packet=null;
switch(apacketType){
case ST_OBJECT_TYPE_INFO_START:
{
packet = new InfoStartRPCPacket();
break;
}
case ST_OBJECT_TYPE_INFO_END:
{
packet = new InfoEndRPCPacket();
break;
}
case ST_OBJECT_TYPE_INFO_ERROR:
{
packet = new InfoErrorRPCPacket();
break;
}
// Basic packets
case ST_OBJECT_TYPE_COLLECTION:
{
packet = new CollectionRPCPacket();
break;
}
case ST_OBJECT_TYPE_CATEGORY:
{
packet = new CategoryRPCPacket();
break;
}
case ST_OBJECT_TYPE_CARD:
{
packet = new CardRPCPacket();
break;
}
case ST_OBJECT_TYPE_MESSAGE:
{
packet = new MessageRPCPacket();
break;
}
case ST_OBJECT_TYPE_GENRE:
{
packet = new GenreRPCPacket();
break;
}
case ST_OBJECT_TYPE_TAG:
{
packet = new TagRPCPacket();
break;
}
case ST_OBJECT_TYPE_USER:
{
packet = new UserRPCPacket();
break;
}
case ST_OBJECT_TYPE_CARDSTATS_CATEGORY:
{
packet = new CardStatsCategoryRPCPacket();
break;
}
case ST_OBJECT_TYPE_CONTENT:
{
packet = new ContentRPCPacket();
break;
}
// Media packets
case ST_OBJECT_TYPE_MEDIA_COLLECTION:
{
packet = new MediaCollectionRPCPacket();
break;
}
case ST_OBJECT_TYPE_MEDIA_CATEGORY:
{
packet = new MediaCategoryRPCPacket();
break;
}
case ST_OBJECT_TYPE_MEDIA_CARD:
{
packet = new MediaCardRPCPacket();
break;
}
case ST_OBJECT_TYPE_MEDIA_TAG:
{
packet = new MediaTagRPCPacket();
break;
}
case ST_OBJECT_TYPE_MEDIA_COLLECTION_BUTTON:
{
packet = new MediaCollectionButtonRPCPacket();
break;
}
// unknown packet
default:
{
packet=null;
break;
}
}
}
子类构造函数:
static int apacketId;
static RPCPacketType apacketType;
static RPCOperationType aoperationType;
static String tmpPacket_objectOid;
static int aobjectId;
static int adataSize;
static String tmpPacket_dataHash;
static RPCPacketDataType adataType;
static byte[] apacketData;
public InfoStartRPCPacket() {
super(apacketId, apacketType, aoperationType, tmpPacket_objectOid, aobjectId,
adataSize, tmpPacket_dataHash, adataType, apacketData);//line 46 from LogCat error
}
LogCat异常:
09-08 11:18:05.614: WARN/System.err(3376): java.lang.NullPointerException
09-08 11:18:05.614: WARN/System.err(3376): at com.stampii.stampii.comm.rpc.RPCPacket.<init>(RPCPacket.java:68)
09-08 11:18:05.614: WARN/System.err(3376): at com.stampii.stampii.comm.rpc.InfoStartRPCPacket.<init>(InfoStartRPCPacket.java:46)
09-08 11:18:05.614: WARN/System.err(3376): at com.stampii.stampii.comm.rpc.RPCPacket.<init>(RPCPacket.java:71)
09-08 11:18:05.614: WARN/System.err(3376): at com.stampii.stampii.user.UserLogin$2.onClick(UserLogin.java:122)
09-08 11:18:05.614: WARN/System.err(3376): at android.view.View.performClick(View.java:2408)
09-08 11:18:05.614: WARN/System.err(3376): at android.view.View$PerformClick.run(View.java:8817)
09-08 11:18:05.614: WARN/System.err(3376): at android.os.Handler.handleCallback(Handler.java:587)
09-08 11:18:05.614: WARN/System.err(3376): at android.os.Handler.dispatchMessage(Handler.java:92)
09-08 11:18:05.614: WARN/System.err(3376): at android.os.Looper.loop(Looper.java:144)
09-08 11:18:05.614: WARN/System.err(3376): at android.app.ActivityThread.main(ActivityThread.java:4937)
09-08 11:18:05.614: WARN/System.err(3376): at java.lang.reflect.Method.invokeNative(Native Method)
09-08 11:18:05.614: WARN/System.err(3376): at java.lang.reflect.Method.invoke(Method.java:521)
09-08 11:18:05.614: WARN/System.err(3376): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
09-08 11:18:05.614: WARN/System.err(3376): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
09-08 11:18:05.624: WARN/System.err(3376): at dalvik.system.NativeStart.main(Native Method)
有关如何解决我的问题的任何建议吗?
答案 0 :(得分:3)
你得到的是NullPointerException,因为(我假设)你没有实例化你在构造函数中使用的任何静态变量。在调用InfoStartRPCPacket()
之前,您需要传入这些参数的值。
然而,这看起来像是一个坏OO的情况,除非你有一个非常具体的需要在你的子类中使用静态变量,我建议你的子构造函数应该接受参数父级,以便您可以优雅地使用您孩子的super(...)
构造函数。像这样:
InfoStartRPCPacket(
int apacketId,
RPCPacketType apacketType,
RPCOperationType aoperationType,
String tmpPacket_objectOid,
int aobjectId,
int adataSize,
String tmpPacket_dataHash,
RPCPacketDataType adataType,
byte[] apacketData) {
super(apacketId, apacketType, aoperationType, tmpPacket_objectOid, aobjectId,
adataSize, tmpPacket_dataHash, adataType, apacketData);
//your custom constructor code here
}
这样,在调用构造函数之前,没有人必须知道实例化所有静态类型变量(反模式称为顺序耦合)。
更好的是,如果您在InfoStartRPCPacket中没有其他工作要做,请完全省略子构造函数方法。它将简单地继承父的构造函数。
答案 1 :(得分:0)
您似乎没有设置或初始化传递给超构造函数的任何变量 - 因此任何作为对象引用的变量都将为null。
答案 2 :(得分:0)
查看代码中的第68行(RPCPacket.java:68
)。由于这里没有相关的行号,我无法弄清楚这一点。似乎您正在访问对象的某些方法/属性而不进行初始化。
答案 3 :(得分:0)
您的RPCPacketType为null且switch()语句引发空指针异常,因为它无法评估apacketType。