我有下面的例子:
public class A implements Serializable {
int a;
B b;
...
@Override
public String toString() {
Gson gson = new Gson();
return gson.toJson(this);
}
}
public class B implements Serializable {
int c;
byte[] d;
...
@Override
public String toString() {
Gson gson = new GsonBuilder().setExclusionStrategies(new BExclusionStrategy()).create();
return gson.toJson(this);
}
public class BExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipClass(Class<?> arg0) {
return false;
}
@Override
public boolean shouldSkipField(FieldAttributes attr) {
return attr.getName().equals("d") && attr.getDeclaringClass() == B.class;
}
}
}
我想在调用类A的toString
方法时排除字段d,因为字节数组非常长。但是如果我在B类中指定了执行策略,它在调用A.toString()
时不适用。但是如果我把执行策略移到类A的toString
方法上,它就能工作,并且字段d被省略了。
为什么会这样呢?另外,类B在多个不同的类中使用,我想省略对所有类打印d。
为什么会这样呢?另外,类B在多个不同的类中使用,我想省略对所有类打印d。
注意:我不想使用transient byte[] d
,这将解决打印问题。我还在B类和excludeFieldsWithoutExposeAnnotation()
类的其他字段上尝试了@ blog,但也不起作用。
1条答案
按热度按时间wsxa1bj11#
但是如果我在B类中指定了执行策略,它在调用
A.toString()
时就不适用了。但是如果我把执行策略移到类A的toString
方法上,它就能工作,并且字段d被省略了。为什么会这样呢?
因为当你调用
A.toString()
,它调用Gson时,它使用反射来序列化A
的字段,然后是B
。由于B.toString()
永远不会被调用,因此您指定的排除策略没有任何效果。我还在B类的其他字段上尝试了@ blog
Gson没有
@Exclude
注解,它只有@Expose
。@Exclude
注解可能来自不同的库,但Gson会忽略它。最简单的解决方案是使用
transient
字段修饰符。如果你不想这样做,那么你可以创建一个配置了自定义排除策略的Gson示例,然后所有的toString()
方法都会使用这个示例。您还可以通过创建自己的@Exclude
注解或类似注解并让排除策略进行检查来使排除策略更通用。但是,由于您关心的似乎是字节数组
byte[] d
的长度,因此您可以在该字段上使用Gson的@JsonAdapter
注解来指定一个自定义适配器,该适配器创建数组的更简洁的JSON表示。