Java 在模型类中添加处理程序对象时,GSON对象序列化中断

Java 在模型类中添加处理程序对象时,GSON对象序列化中断,java,android,json,serialization,gson,Java,Android,Json,Serialization,Gson,我在Android中有一个POJO,它是用GSON从服务器的JSON响应序列化的,没有任何问题 public ExampleClass implements Serializable { @Expose String someProperty; } 出于某种原因,我希望在类中存储一个处理程序对象,如: public ExampleClass implements Serializable { private Handler handler = new Handler

我在Android中有一个POJO,它是用GSON从服务器的JSON响应序列化的,没有任何问题

public ExampleClass implements Serializable {
    @Expose 
    String someProperty;
}
出于某种原因,我希望在类中存储一个处理程序对象,如:

public ExampleClass implements Serializable {

    private Handler handler = new Handler();

    @Expose 
    String someProperty;
}
添加此额外行后,序列化将中断为

java.lang.RuntimeException: Failed to invoke public com.example.android.ExampleClass() with no args
我尝试为我的类添加一个无参数构造函数,但没有成功。 我尝试过使处理程序对象暂时化,但仍然没有成功


更新:

所以,我找到了解决办法。这里的问题是处理程序对象在完成对象的序列化之前被初始化

因此,这并没有破坏序列化:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;
}
但是在哪里初始化它呢?如果我尝试在无参数构造函数中执行此操作,序列化将再次中断:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;

    public ExampleClass() {
        handler = new Handler(); // breaks serialization 
    }
}
如果我稍后在序列化完成时对其进行初始化,它将工作:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;

    public void functionCalledInTheFuture() {
        handler = new Handler(); // works
    }
}

我不完全理解这一点,所以如果有人能向我解释,请不要犹豫!:)

嗯。。。这很有趣,因为
transient
关键字应该可以做到这一点。但是这只是一个普通用例的快捷方式。如果处理序列化过程的库或代码忽略它,则它可能无法工作

有一篇很好的文章介绍了JAVA()中的序列化主题简而言之:您可以自定义
排除策略
,为类添加专用行为

代码突出显示:

ExclusionStrategy strategy = new ExclusionStrategy() {
    @Override
    public boolean shouldSkipField(FieldAttributes field) {
        if (field.getDeclaringClass() == MyClass.class && field.getName().equals("other")) {
            return true;
        }
        if (field.getDeclaringClass() == MySubClass.class && field.getName().equals("otherVerboseInfo")) {
            return true;
        }
        return false;
    }

    @Override
    public boolean shouldSkipClass(Class<?> clazz) {
        return false;
    }
};

Gson gson = new GsonBuilder()
  .addSerializationExclusionStrategy(strategy)
  .create();
String jsonString = gson.toJson(source);

assertEquals(expectedResult, jsonString);
ExclutionStrategy=新的ExclutionStrategy(){
@凌驾
公共布尔值shouldSkipField(字段属性字段){
如果(field.getDeclaringClass()==MyClass.class&&field.getName().equals(“其他”)){
返回true;
}
如果(field.getDeclaringClass()==MySubClass.class&&field.getName().equals(“otherVerboseInfo”)){
返回true;
}
返回false;
}
@凌驾
公共布尔shouldSkipClass(类clazz){
返回false;
}
};
Gson Gson=new GsonBuilder()
.AddSerializationExclutionStrategy(策略)
.create();
字符串jsonString=gson.toJson(源代码);
资产质量(预期结果、jsonString);

是的。。对于您的问题来说,这可能是一种过分的做法,但它应该适用于所有用例

不确定您为什么需要处理程序,但这应该有助于使用
transient
关键字将其从序列化中排除:
private transient handler=new handler()
谢谢@Mykhailo的回答,我在问题的结尾写道,添加临时关键字没有帮助oops没有注意到。您是否尝试添加公共构造函数
public ExampleClass(){}
?我已使用解决方案更新了该问题这是一个很好的解决方法!因为处理程序没有在c'tor中初始化(隐式或显式),所以序列化机制在调用c'tor时跳过它。美好的不过,我仍然认为让处理者离开那里会更好谢谢你@ymz,我已经找到了解决我问题的方法并更新了我的问题,请看一下,也许你明白这里发生了什么