java.lang.RuntimeException:无法调用没有参数的公共 com.example.syncapp.MessageBase()

Posted

技术标签:

【中文标题】java.lang.RuntimeException:无法调用没有参数的公共 com.example.syncapp.MessageBase()【英文标题】:java.lang.RuntimeException: Failed to invoke public com.example.syncapp.MessageBase() with no args 【发布时间】:2013-02-26 00:34:20 【问题描述】:
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 

  System.out.println(request.getParameter("msg").toString());
  String data = request.getParameter("msg").toString();
  Gson gson = new Gson();
  MessageBase msggg = gson.fromJson(data, MessageBase.class);
  //System.out.println(msggg.Id + msggg.MessageText);


public abstract class MessageBase implements Serializable 
  public int Id;
  public String MessageText;
  public Date ReceiveDate;


public class SyncSmsMessage extends MessageBase 
  public String SenderNum;  

代码在MessageBase msggg=gson.fromJson(data, MessageBase.class); 之前有效。我得到了这个例外:

java.lang.RuntimeException: Failed to invoke public com.example.syncapp.MessageBase() with no args
  at com.google.gson.internal.ConstructorConstructor$2.construct(ConstructorConstructor.java:94)
  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
  at com.google.gson.Gson.fromJson(Gson.java:795)
  at com.google.gson.Gson.fromJson(Gson.java:761)
  at com.google.gson.Gson.fromJson(Gson.java:710)
  at com.google.gson.Gson.fromJson(Gson.java:682)
  at androidServlet.doPost(AndroidServlet.java:75)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

我需要做什么? 我将 .jar 放在 lib 文件夹中,我认为 tomcat 可以很好地加载 .jar。

【问题讨论】:

【参考方案1】:

来自GSON User Guide

在反序列化 Object 时,Gson 需要创建一个类的默认实例 [...] 用于序列化和反序列化的行为良好的类应该有一个 no -参数构造函数

您的问题是 GSON 的 Instance Creator 需要在要反序列化 JSON 响应的类中使用无参数构造函数,即 MessageBase

否则,您需要编写自己的Instance Creator,例如this

【讨论】:

另外,GSON 创建的类不能是抽象的,所以即使使用正确的构造函数,上面的代码也会失败。【参考方案2】:

我在使用改造时遇到了同样的问题,并发现这是在使用 abstract 类时发生的,所以我创建了 extends 抽象类的空类 (MessageBase)像这样:

public class BaseResponse extends MessageBase 


现在使用具有MessageBase 的所有字段的BaseResponse

【讨论】:

【参考方案3】:

抽象类不能被实例化,只能被子类化。抽象方法主体必须为空(无花括号)。 从公共 MessageBase 中删除“抽象”,你就可以开始了。

查看链接Java Abstract Classes

【讨论】:

【参考方案4】:

确定!

1- 类implements Serializable

2- 即使是子类也不抽象

3- 应该是公开的

【讨论】:

【参考方案5】:

问题示例:

你有一个由抽象类成员组成的抽象类,然后你扩展这个主类及其成员。

public abstract class Receipt implements Serializable 

    @Expose
    protected ReceiptMainDetails mainDetails;

    @Expose
    protected ReceiptDetails payerReceiptDetails;

    @Expose
    protected ReceiptDetails payeeReceiptDetails;

(细节也很抽象)

public class TransferReceipt extends Receipt 

    public TransferReceipt() 

    public TransferReceipt(TransferDetails body, Payer payer, Payee payee) 
        super(body, payer, payee);
    

    public  static class TransferDetails extends ReceiptMainDetails 

        public TransferDetails() 

    

(其他细节也有所扩展)

GSON 将无法将 json 转换为对象。

解决方案

Receipt 可以是抽象的,但它的成员必须是具体的类,即使您可以再次扩展它们。

测试您的解决方案

@Test
public void testGson() 

    String jsonString = "youChooseWhatIsHere";

    Gson gson = new Gson();

    TransferReceipt receipt = gson.fromJson(jsonString, TransferReceipt.class);

    String actualReceiptJson = gson.toJson(receipt);

    System.out.println(jsonString);
    System.out.println(actualReceiptJson);
    System.out.println(receipt);

【讨论】:

以上是关于java.lang.RuntimeException:无法调用没有参数的公共 com.example.syncapp.MessageBase()的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 按钮导致崩溃

添加 ImageView 时应用程序崩溃?