我有一个 Item 接口,用于创建和存储游戏物品。这些物品以矩阵的形式存储在玩家的库存中(IItem[][]库存)。当尝试实现读取和写入功能(将对象转换为字符串并进行转换)时,出现错误。如果我创建一个清单作为这些对象的数组,那么 JSON 在数据类型中会混淆(错误代码如下),我尝试仅从 1 个特定对象创建相同的矩阵,而不使用接口,一切正常,但这不是我需要的。我可以断定问题出在注释中。
错误代码: 线程“main”中出现异常 com.fasterxml.jackson.databind.exc.InvalidTypeIdException:无法解析类型 id 'IItem;'作为
items.IItem[]
的子类型:已知类型 ids = [钻石、草、剑](对于 POJO 属性“库存”)
主要
import items.Grass;
import items.IItem;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Player player = new Player(new IItem[][]{{new Grass(5, 2)}},12,20);
player.print();
System.out.println();
String data = player.write();
System.out.println(data);
System.out.println();
Player player2 = Player.read(data);
player2.print();
}
}
玩家
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import items.Diamond;
import items.Grass;
import items.IItem;
import items.Sword;
import java.io.IOException;
public class Player {
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Grass.class, name = "Grass"),
@JsonSubTypes.Type(value = Sword.class, name = "Sword"),
@JsonSubTypes.Type(value = Diamond.class, name = "Diamond")
})
private IItem[][] inventory;
private int health;
private int maxHealth;
public Player() {
}
@JsonCreator
public Player(
@JsonProperty("inventory") IItem[][] inventory,
@JsonProperty("health") int health,
@JsonProperty("maxHealth") int maxHealth) {
this.inventory = inventory;
this.health = health;
this.maxHealth = maxHealth;
}
public void print() {
System.out.println("Player=h" + health + ",m" + maxHealth);
System.out.println("Inventory has:");
for (int i = 0; i < inventory.length; i++) {
for (int j = 0; j < inventory[i].length; j++) {
if (inventory[i][j] != null) {
System.out.print(" - ");
inventory[i][j].print();
}
}
}
}
public String write() throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
public static Player read(String data) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(data, Player.class);
}
public IItem[][] getInventory() {
return inventory;
}
public void setInventory(IItem[][] inventory) {
this.inventory = inventory;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getMaxHealth() {
return maxHealth;
}
public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}
}
物品接口(IItem)
package items;
public interface IItem {
void print ();
}
草
package items;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Grass implements IItem {
public String name = "grass block";
public int count;
public int weight;
@JsonCreator
public Grass(@JsonProperty("count") int count, @JsonProperty("weight") int weight) {
this.count = count;
this.weight = weight;
}
@Override
public void print() {
System.out.println(name + "=c:" + count + ",w:" + weight);
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
public int getWeight() {
return weight;
}
}
剑
package items;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Sword implements IItem{
public String name = "sword";
public int count, damage;
public Sword (@JsonProperty("count")int count,@JsonProperty("damage") int damage) {
this.count=count;
this.damage=damage;
}
@Override
public void print() {
System.out.println(name+"=c:"+count+",d:"+damage);
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
public int getDamage() {
return damage;
}
}
钻石
package items;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Diamond implements IItem{
public String name = "sword";
public int count;
public Diamond(@JsonProperty("count")int count) {
this.count=count;
}
@Override
public void print() {
System.out.println(name+"=c:"+count);
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
}
这是一个测试项目
我尝试进行注释,但它们仅在 1 个对象的情况下有帮助,并且 对象的规则矩阵(IItem[] inventory)。
我通过将注释从 Player 移动到界面(IItem)来修复它
已编辑项目
package items;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Diamond.class, name = "Diamond"),
@JsonSubTypes.Type(value = Grass.class, name = "Grass"),
@JsonSubTypes.Type(value = Sword.class, name = "Sword")
})
public interface IItem {
void print ();
}
已编辑的玩家
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import items.IItem;
import java.io.IOException;
public class Player {
private IItem[][] inventory;
private int health;
private int maxHealth;
public Player() {
}
@JsonCreator
public Player(
@JsonProperty("inventory") IItem[][] inventory,
@JsonProperty("health") int health,
@JsonProperty("maxHealth") int maxHealth) {
this.inventory = inventory;
this.health = health;
this.maxHealth = maxHealth;
}
public void print() {
System.out.println("Player=h" + health + ",m" + maxHealth);
System.out.println("Inventory has:");
for (int i = 0; i < inventory.length; i++) {
for (int j = 0; j < inventory[i].length; j++) {
if (inventory[i][j] != null) {
System.out.print(" - ");
inventory[i][j].print();
}
}
}
}
public static String write(Player player) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(player);
}
public static Player read(String data) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(data, Player.class);
}
public IItem[][] getInventory() {
return inventory;
}
public void setInventory(IItem[][] inventory) {
this.inventory = inventory;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getMaxHealth() {
return maxHealth;
}
public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}
}
控制台结果:
Player=h12,m20
Inventory has:
- grass block=c:5,w:2
- sword=c:1,d:12
- sword=c:8
{"inventory":[[{"type":"Grass","count":5,"weight":2,"name":"grass block"}],[{"type":"Sword","count":1,"damage":12,"name":"sword"}],[{"type":"Diamond","count":8,"name":"sword"}]],"health":12,"maxHealth":20}
Player=h12,m20
Inventory has:
- grass block=c:5,w:2
- sword=c:1,d:12
- sword=c:8