配置序列化与遍历
配置 API 能直接存基本类型和 String、List。但自定义对象(如你写的 Person 类)直接 set 存不进去——要靠序列化。
哪些类型能直接 set
所有 getXxx 方法对应的类型都能直接存(int、String、List<String> 等)。还有一些 Bukkit 类型(如 ItemStack)也能直接存——判断标准是看 JavaDoc 里它是否实现了 ConfigurationSerializable。
自定义类型默认不能直接存:
java
Person person = new Person("tdiant", "hello!!");
getConfig().set("demo", person);
getConfig().get("demo"); // 拿不回来,存了个寂寞序列化自定义类型
让自定义类实现 ConfigurationSerializable,提供 serialize() 和 deserialize():
java
public class Person implements ConfigurationSerializable {
public String name;
public String introduction;
public Person(String name, String introduction) {
this.name = name;
this.introduction = introduction;
}
// 序列化:把对象转成 Map 存进配置
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("introduction", introduction);
return map;
}
// 反序列化:从 Map 还原对象
public static Person deserialize(Map<String, Object> map) {
return new Person(
(String) map.get("name"),
(String) map.get("introduction")
);
}
}全限定类名会被记录
序列化后配置里会自动写入这个对象的完整类名,反序列化时按它找类。所以改包名/类名会导致旧配置无法反序列化。
现在能直接存取了:
java
Person person = new Person("tdiant", "hello!!");
getConfig().set("demo", person);
saveConfig();
// 读回来
Person loaded = (Person) getConfig().get("demo");配置文件里长这样:
yaml
demo:
==: com.example.Person
name: tdiant
introduction: hello!!==: 那行就是类名标记。
遍历 ConfigurationSection
配置可能有不确定的子键(如每个玩家一个键),需要遍历。用 getKeys / getValues:
java
ConfigurationSection section = getConfig().getConfigurationSection("Data");
if (section != null) {
// 遍历所有子键名
for (String key : section.getKeys(false)) {
getLogger().info("玩家: " + key);
}
// 遍历所有子键值
for (String key : section.getKeys(false)) {
int score = section.getInt(key + ".Score");
getLogger().info(key + " 的分数: " + score);
}
}getKeys 的参数
java
section.getKeys(false) // 只取直接子键
section.getKeys(true) // 递归取所有后代键区分直接子键和递归
getKeys(false) 只给第一层键名(如 player1、player2)。getKeys(true) 会把 player1.Score、player1.NickName 全部展开。遍历玩家列表用 false。
实战:遍历玩家数据
配置:
yaml
Data:
player1:
Score: 50
NickName: A
player2:
Score: 80
NickName: B遍历取出每个玩家分数:
java
ConfigurationSection data = getConfig().getConfigurationSection("Data");
int total = 0;
for (String name : data.getKeys(false)) {
total += data.getInt(name + ".Score");
}
getLogger().info("总分数: " + total);序列化解决"存对象",遍历解决"存动态数据"。下一篇多线程与多任务。
