Note: Every time I go to type up this question, I think I see something, but it never pans out, so for the third or fourth time.
注:每次我去键入这个问题时,我想我看到了一些东西,但它从来没有出现过,所以在第三或第四次。
Synopsis: I am trying to serialize an object that inherits from the base Response class using the Response class, of which the subclass may have non-primitive field types.
概要:我正在尝试使用Response类对继承自基响应类的对象进行序列化,其中的子类可能具有非基元字段类型。
The code is as such (warning: large and not elegant), ordered from the specific class (SpecificResponse), as extended from a common class (CommonResponse), which is a concrete implementation of the abstract class (Response), driven by a test program (Program).
代码是这样的(警告:大而不优雅),来自特定类(特异响应),从公共类(CommonResponse)扩展而来,后者是抽象类(响应)的具体实现,由测试程序(程序)驱动。
// SpecificResponse.java
package com.jdgj.thinking;
public final class SpecificResponse extends CommonResponse {
public String hell;
public int trike;
public short tail;
public SpecificResponse() {
super();
}
}
SpecifcResponse extends CommonResponse:
SpecifcResponse CommonResponse延伸:
// CommonResponse.java
package com.jdgj.thinking;
public class CommonResponse extends Response {
public int thing2;
public Value value;
@Override
protected void initialize() {
System.out.println("hello!");
value = new Value();
}
}
For testing purposes, I just made a simple Value object:
为了测试目的,我做了一个简单的Value对象:
// Value.java
package com.jdgj.thinking;
public class Value {
public int five;
}
And, that which does a lot of work, and also the foundation for CommonResponse, the Response class:
做了很多工作,也是CommonResponse课程的基础,Response类:
// Response.java
package com.jdgj.thinking;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
public abstract class Response {
public static Class<?> fromClassSignature(List<String> signature) throws IllegalArgumentException, IllegalStateException, ClassNotFoundException {
if (signature == null || signature.size() == 0) {
throw new IllegalArgumentException("Null or empty Response class signature.");
}
String lastClassName = null;
for (String line : signature) {
if (line.startsWith("class:")) {
lastClassName = line.split(":")[1];
}
}
if (lastClassName == null) {
throw new IllegalStateException("Could not find the Response class name.");
}
Class<?> c = Class.forName(lastClassName);
lastClassName = null;
Class<?> sc = c.getSuperclass();
while (sc != null && !sc.equals(Response.class)) {
sc = sc.getSuperclass();
}
if (sc != null) {
sc = null;
return c;
} else {
return null;
}
}
protected abstract void initialize();
private String getFieldSignature(Field field) {
return "field:" + field.getName() + "|" + field.getType().getCanonicalName();
}
private List<String> serializeObject(Class<?> c, Object o) {
List<String> serialization = new ArrayList<String>(0);
serialization.add("class:" + c.getName());
for (Field f : c.getDeclaredFields()) {
if (!f.isSynthetic() && Modifier.isPublic(f.getModifiers())) {
StringBuilder sb = new StringBuilder(getFieldSignature(f));
Class<?> t = f.getType();
Object value = null;
try {
value = f.get(o);
System.out.println(f.getName() + "=" + value);
if (t.isPrimitive() || t.equals(String.class)) {
sb.append("`" + value.toString() + "");
}
} catch (NullPointerException e) {
if (t.isPrimitive() || t.equals(String.class)) {
sb.append("`");
} else {
System.out.println("UNEXPECTED NULL POINTER EXCEPTION");
}
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
serialization.add(sb.toString());
if (value != null) {
if (!(t.isPrimitive() || t.equals(String.class))) {
serialization.addAll(serializeObject(t, value));
}
}
}
sb = null;
t = null;
}
}
return serialization;
}
private List<String> describeClass(Class<?> c) {
List<String> description = new ArrayList<String>(0);
description.add("class:" + c.getName());
for (Field f : c.getDeclaredFields()) {
if (!f.isSynthetic() && Modifier.isPublic(f.getModifiers())) {
description.add(getFieldSignature(f));
Class<?> t = f.getType();
if (!(t.isPrimitive() || t.equals(String.class))) {
description.addAll(describeClass(t));
}
t = null;
}
}
return description;
}
public final List<String> getSerializedObject() {
Class<?> c = getClass();
List<String> object = new ArrayList<String>(0);
while (c != null && !c.equals(Response.class)) {
object.addAll(0, serializeObject(c, this));
c = c.getSuperclass();
}
c = null;
return object;
}
public final List<String> getClassSignature() {
Class<?> c = getClass();
List<String> signature = new ArrayList<String>(0);
while (c != null && !c.equals(Response.class)) {
signature.addAll(0, describeClass(c));
c = c.getSuperclass();
}
c = null;
return signature;
}
}
These classes are driven by a 'dev-test' program for now:
这些类目前由一个“开发测试”程序驱动:
// Program.java
import com.jdgj.thinking.Response;
import com.jdgj.thinking.SpecificResponse;
public class Program {
private static void printClassSignature(Response response) {
for (String line : response.getClassSignature()) {
System.out.println(line);
}
}
private static void printSerializedObject(Response response) {
for (String line : response.getSerializedObject()) {
System.out.println(line);
}
}
public static void main(String[] args) {
String CN_SPECRSP = "com.jdgj.thinking.SpecificResponse";
Class<?> response = null;
try {
response = Response.fromClassSignature(new SpecificResponse().getClassSignature());
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
if (response != null) {
System.out.println("Expected: " + CN_SPECRSP + "; Actually: " + response.getCanonicalName());
Response rsp = null;
try {
rsp = (Response)response.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (rsp != null) {
//printClassSignature(rsp);
printSerializedObject(rsp);
rsp = null;
}
}
response = null;
}
}
}
}
Here's the output:
输出:
Expected: com.jdgj.thinking.SpecificResponse; Actually: com.jdgj.thinking.SpecificResponse
hell=null
trike=0
tail=0
thing2=0
value=null
class:com.jdgj.thinking.CommonResponse
field:thing2|int`0
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String`
field:trike|int`0
field:tail|short`0
Why does value report null?
为什么value report null?
In both not having and having a constructor defined in CommonResponse to initialize the Value instance, it's still shown as null. If I uncomment the Program.getClassSignature
method, the code delves into the Value object to get the five
field:
在这两种方法中,都没有定义一个构造函数来初始化值实例,它仍然显示为空。如果我取消对程序的评论。getClassSignature方法,代码深入到Value对象中,得到5个字段:
Expected: com.jdgj.thinking.SpecificResponse; Actually: com.jdgj.thinking.SpecificResponse
class:com.jdgj.thinking.CommonResponse
field:thing2|int
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.Value
field:five|int
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String
field:trike|int
field:tail|short
hell=null
trike=0
tail=0
thing2=0
value=null
class:com.jdgj.thinking.CommonResponse
field:thing2|int`0
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String`
field:trike|int`0
field:tail|short`0
I feel as if I've exhausted my Google-fu, and I feel like I'm missing something just.. blatantly obvious, but I cannot think of the reason, or the right query to ask Google. Everyone keeps providing ways to get primitive fields, but that is not what I am seeking. I therefore submit to the guidance of SO.
我觉得我的谷歌功夫已经用完了,我觉得我错过了一些东西。显而易见,但我想不出原因,也想不出问谷歌的正确查询。每个人都在不断地提供获取原始字段的方法,但这不是我想要的。因此,我服从于SO的指导。
1 个解决方案
#1
0
As Holger said you never initialize that field. You have a initialize() method to do it, but never invoke it. Of course if you call getClassSignature() you get info about your field, actually it's there; you got a field named value of type com.jdgj.thinking.Value in your class, but it never has been instantiated, so that field value is null.
正如霍尔格所说,你从来没有初始化那个字段。您有一个initialize()方法来实现它,但是永远不要调用它。当然,如果你调用getClassSignature()你会得到关于你的字段的信息,实际上它就在那里;你得到一个名为type com.jdgj.thinking的字段。类中的值,但从未实例化过,因此字段值为null。
#1
0
As Holger said you never initialize that field. You have a initialize() method to do it, but never invoke it. Of course if you call getClassSignature() you get info about your field, actually it's there; you got a field named value of type com.jdgj.thinking.Value in your class, but it never has been instantiated, so that field value is null.
正如霍尔格所说,你从来没有初始化那个字段。您有一个initialize()方法来实现它,但是永远不要调用它。当然,如果你调用getClassSignature()你会得到关于你的字段的信息,实际上它就在那里;你得到一个名为type com.jdgj.thinking的字段。类中的值,但从未实例化过,因此字段值为null。