<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://mineplugin.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=1216500866</id>
	<title>Minecraft插件百科 - 用户贡献 [zh-cn]</title>
	<link rel="self" type="application/atom+xml" href="https://mineplugin.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=1216500866"/>
	<link rel="alternate" type="text/html" href="https://mineplugin.org/%E7%89%B9%E6%AE%8A:%E7%94%A8%E6%88%B7%E8%B4%A1%E7%8C%AE/1216500866"/>
	<updated>2026-04-25T13:36:26Z</updated>
	<subtitle>用户贡献</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://mineplugin.org/index.php?title=Configuration_API_Reference&amp;diff=9057</id>
		<title>Configuration API Reference</title>
		<link rel="alternate" type="text/html" href="https://mineplugin.org/index.php?title=Configuration_API_Reference&amp;diff=9057"/>
		<updated>2019-10-11T19:35:08Z</updated>

		<summary type="html">&lt;p&gt;1216500866：​/* 实现获取 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Configuration API Reference/en|点击此处浏览原文]]&lt;br /&gt;
{{待翻译}}&lt;br /&gt;
&lt;br /&gt;
Configuration API是一个能够帮助开发者快速解析与编辑配置文件的工具，它让配置文件更简单、更容易读写。无论是什么，这个API可以帮助你更容易的存储你插件的配置信息。目前只有这个 [http://en.wikipedia.org/wiki/YAML YAML] configurations 可以用。然而这个API被设计有广泛的拓展性，这意味着它允许你实现其他需要实现的东西。&lt;br /&gt;
&lt;br /&gt;
Configuration API存在于 org.bukkit.configuration 和 org.bukkit.configuration.file 这两个包中。如果是创建在 1.1-R5 版本之前的插件，就只能用老版本并且与本文截然不同的API了，这些老版API在老版本的org.bukkit.util.configuration包中。这些内容彼此互不兼容，并且因为老的方法太过时了，所以在新版中已被删去。&lt;br /&gt;
&lt;br /&gt;
本文假定你对面向对象思想、Java与Bukkit插件编写的核心思想有着相当深的了解与认识。 本文并非JavaDoc[https://hub.spigotmc.org/javadocs/bukkit/index.html?org/bukkit/configuration/file/FileConfiguration.html FileConfiguration Class]的替代品。&lt;br /&gt;
&lt;br /&gt;
（译者注：上方链接因过时，已经替换到了最新的新版链接当中，内容稍微与原文有所不符，但影响不大）&lt;br /&gt;
&lt;br /&gt;
== 基本论述  ==&lt;br /&gt;
&lt;br /&gt;
=== 配置文件对象 ===&lt;br /&gt;
当你的插件主类继承 [http://jd.bukkit.org/doxygen/d7/deb/classorg_1_1bukkit_1_1plugin_1_1java_1_1JavaPlugin.html JavaPlugin] 类时也会继承父类 JavaPlugin 类的方法和属性。 在被继承的方法中, &#039;&#039;[http://jd.bukkit.org/doxygen/d7/deb/classorg_1_1bukkit_1_1plugin_1_1java_1_1JavaPlugin.html#a79493f3bc9db2acbf9405c3a33e0acfd getConfig()]&#039;&#039; 返回的是一个 [http://jd.bukkit.org/doxygen/dd/d7c/classorg_1_1bukkit_1_1configuration_1_1file_1_1FileConfiguration.html FileConfiguration]类型的对象。这个对象就代表你插件数据文件夹里的&#039;&#039;config.yml&#039;&#039; 文件。&lt;br /&gt;
&lt;br /&gt;
你的插件在第一次调用&#039;&#039;getConfig()&#039;&#039;方法时，会从你插件的jar文件中读取相应的&#039;&#039;config.yml&#039;&#039; 文件，同时从jar中的&#039;&#039;config.yml&#039;&#039;文件里加载相应的默认数据。 需要注意的是，在第一次使用之后若再次调用&#039;&#039;getConfig()&#039;&#039;方法，只会返回内存中保存的&#039;&#039;FileConfiguration&#039;&#039; 对象，而并非磁盘上保存的最新的，并且你对这个对象进行的修改并不会被保存，除非你手动保存。同理，在第一次调用&#039;&#039;getConfig()&#039;&#039;方法之后，对磁盘上的config.yml文件的修改不会被同步给这个对象。如果在 plugins 文件夹中对应的插件文件夹里不存在 &#039;&#039;config.yml&#039;&#039; ，这时会等价于存在一个空的&#039;&#039;config.yml&#039;&#039;文件, 也会加载一个空的&#039;&#039;FileConfiguration&#039;&#039;对象。&lt;br /&gt;
&lt;br /&gt;
{{warning| 如果你在利用&#039;&#039;getConfig()&#039;&#039;的返回值，请不要把它赋给一个变量来使用}}&amp;lt;br /&amp;gt;&lt;br /&gt;
{{warning| 如果需要这样的话，一定要记住在重载配置文件后，再把 &#039;&#039;getConfig()&#039;&#039; 方法的返回值分配给那个变量}} &amp;lt;br /&amp;gt;&lt;br /&gt;
{{warning| 保险起见，推荐你尽可能的直接用&#039;&#039;getConfig()&#039;&#039;方法，而不是将其分配给一个变量}}&lt;br /&gt;
&lt;br /&gt;
===  键   ===&lt;br /&gt;
&lt;br /&gt;
一个配置文件由键值对构成，键是一个字符串。键对应的值可能是一个 &#039;&#039;ConfigurationSection&#039;&#039; 对象或是其他形式的数据.  &#039;&#039;getKeys(boolean)&#039;&#039; 方法会返回一个存有当前&#039;&#039;FileConfigurationSection&#039;&#039;所有键的集合，布尔值决定着是否递归地返回集合，如果值为true，将返回指定部分的所有键与所有对应子键, 如果为false则只会返回指定部分的所有键（不含子键）。 若要获取特定部分的所有键，需调用特定部分&#039;&#039;ConfigurationSection&#039;&#039;对象的 &#039;&#039;getKeys(boolean)&#039;&#039; 方法。 你可使用&#039;&#039;getConfigurationSection(String)&#039;&#039;方法来获取这个部分。&lt;br /&gt;
&lt;br /&gt;
{{warning| getKeys(boolean)方法返回的是一个字符串[http://download.oracle.com/javase/1,5.0/docs/api/java/util/Set.html 集合]}}&lt;br /&gt;
&lt;br /&gt;
=== 路径 ===&lt;br /&gt;
&lt;br /&gt;
Configuration API 中使用路径（Path）来构成一个独立的键值对。 一个路径是一层层的键的组合，被用来联系所对应的值。 每一层都用路径分隔符区分开来，路径分隔符通常是 &#039;.&#039; (段落)。 举个例子，下面的YMAL文件有着下面这些组路径。&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;yaml&amp;quot;&amp;gt;key: value&lt;br /&gt;
one:&lt;br /&gt;
  two: value&lt;br /&gt;
  three:&lt;br /&gt;
    - values&lt;br /&gt;
    - values&lt;br /&gt;
    - values&lt;br /&gt;
  four: &lt;br /&gt;
    five: value&lt;br /&gt;
  *:&lt;br /&gt;
    six: value&lt;br /&gt;
    seven: value&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*key&lt;br /&gt;
*one&lt;br /&gt;
*one.two&lt;br /&gt;
*one.three&lt;br /&gt;
*one.four&lt;br /&gt;
*one.four.five&lt;br /&gt;
*one.*&lt;br /&gt;
*one.*.six&lt;br /&gt;
*one.*.seven&lt;br /&gt;
&lt;br /&gt;
=== 默认值 ===&lt;br /&gt;
&lt;br /&gt;
你的插件jar中应该为用户准备一个默认的&#039;&#039;config.yml&#039;&#039;文件。当&#039;&#039;config.yml&#039;&#039;丢失或是不完整的情况发生时，要获取的值将会从jar内的 &#039;&#039;config.yml&#039;&#039;文件来获取。被准备的文件必须被命名为 &#039;&#039;config.yml&#039;&#039; ，且应当放在与 [[Plugin YAML|plugin.yml]]相同目录下。你应该在jar里的&#039;&#039;config.yml&#039;&#039;里准备一个完整的基本结构。你可以在插件主类的适当的地方使用 saveDefaultConfig() 方法把jar里的config.yml文件从jar中复制到插件配置文件夹里。&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.saveDefaultConfig()&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果你想动态的把一对键值作为默认值，你可以利用&#039;&#039;addDefault(String, Object)&#039;&#039; 方法和 &#039;&#039;addDefaults(Map&amp;amp;lt;String,Object&amp;amp;gt;)&#039;&#039; 方法。&lt;br /&gt;
&lt;br /&gt;
有时如果你想添加一对新的键值给一个现存的 config.yml 文件，你可以通过通过传参布尔值 true给ConfigurationOptions对象里的copyDefaults方法来实现这一目的。 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.getConfig().options().copyDefaults(true)&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 创建一份config.yml的拷贝 ====&lt;br /&gt;
你可以使用JavaPlugin类中的saveDefaultConfig()方法，将jar中的config.yml拷贝一份至插件的数据文件夹中&amp;lt;ref&amp;gt;/plugins/你的插件/&amp;lt;/ref&amp;gt; . saveDefaultConfig()并不会覆盖已有的文件.&lt;br /&gt;
&lt;br /&gt;
=== 获得值 ===&lt;br /&gt;
&lt;br /&gt;
你可以使用一堆 getter 方法来获取配置文件中的值。这些 getter 方法你可以在[http://jd.bukkit.org/doxygen/dd/d7c/classorg_1_1bukkit_1_1configuration_1_1file_1_1FileConfiguration.html 这里]找到。每个 getter 方法 takes a configuration path detailed above. 一般条件下你应该需要这些 getter 来获取值： &lt;br /&gt;
&lt;br /&gt;
*getBoolean(String)   获取键对应的类型为boolean的值&lt;br /&gt;
*getInt(String)   获取键对应的类型为 int 的值&lt;br /&gt;
*getString(String)   获取键对应的类型为 String 的值&lt;br /&gt;
*getList(String)    获取键对应的类型为 List 的值&lt;br /&gt;
*getStringList(String)    &lt;br /&gt;
&lt;br /&gt;
==== HashMaps  ====&lt;br /&gt;
&lt;br /&gt;
In the case of HashMaps as a value, they are treated differently than other forms of data. There is a restriction for Map types. It must use a String as a key, and the value but be either a boxed primitive, String, List, Map, or a ConfigurationSerializable type. They will lose their type.&lt;br /&gt;
&lt;br /&gt;
To get a &#039;&#039;HashMap&#039;&#039;, a &#039;&#039;ConfigurationSection&#039;&#039; must must first be retrieved. You can return the configuration with  getConfigurationSection method. The getValues method will return the values in the ConfigurationSection as a map, it takes a boolean which controls if the nested maps will be returned in the map. You can obtain the original map by invoking getValues(false) on the returned ConfigurationSection. Due to the way Java handles generic classes, type information will be lost, thus a cast will need to be performed to set the original type information. The API makes no guarantees that the cast you perform will be safe.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.getConfig().getConfigurationSection(&amp;quot;path.to.map&amp;quot;).getValues(false)&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 设定值 ===&lt;br /&gt;
&lt;br /&gt;
Writing values involves invoking the &#039;&#039;set(String, Object)&#039;&#039; method on an instance of Configuration. Unlike the different get methods that &#039;&#039;FileConfiguration&#039;&#039; has, there is only one set method. Not all objects can be set, only primitive types, &#039;&#039;String&#039;&#039;, &#039;&#039;Lists&#039;&#039;, and types that implement &#039;&#039;ConfigurationSerializable&#039;&#039;, such as &#039;&#039;Vector&#039;&#039; and &#039;&#039;ItemStack&#039;&#039;, can be set. To erase a value supply null as a parameter. All changes made by set will only affect the copy of the configuration in memory, and will not persist beyond restarting the server until the configuration is saved. Following are some example uses: &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;// setting a boolean value&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.boolean&amp;quot;, true);&lt;br /&gt;
&lt;br /&gt;
// setting a String&lt;br /&gt;
String stringValue = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.string&amp;quot;, stringValue);&lt;br /&gt;
&lt;br /&gt;
// setting an int value&lt;br /&gt;
int integerValue = 8;&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.integer&amp;quot;, integerValue);&lt;br /&gt;
&lt;br /&gt;
// Setting a List of Strings&lt;br /&gt;
// The List of Strings is first defined in this array&lt;br /&gt;
List&amp;lt;String&amp;gt; listOfStrings = Arrays.asList(&amp;quot;Hello World&amp;quot;, &amp;quot;Welcome to Bukkit&amp;quot;, &amp;quot;Have a Good Day!&amp;quot;);&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.list&amp;quot;, listOfStrings);&lt;br /&gt;
&lt;br /&gt;
// Setting a vector&lt;br /&gt;
// event is assumed to be an existing event inside an &amp;quot;onEvent&amp;quot; method.&lt;br /&gt;
Vector vector = event.getPlayer().getLocation().toVector();&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.vector&amp;quot;, vector);&lt;br /&gt;
&lt;br /&gt;
// Erasing a value&lt;br /&gt;
this.getConfig().set(&amp;quot;path.to.value&amp;quot;, null);&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==== HashMaps  ====&lt;br /&gt;
&lt;br /&gt;
When HashMaps are used as a value, they are treated slightly differently. The Map must parameterized with a String type for the key, and the value must be parameterized as a boxed primitive, String, List, Map, or a ConfigurationSerializable.&lt;br /&gt;
&lt;br /&gt;
While you can use the set method to directly set a HashMap to a key, you cannot directly retrieve the Map back with the get method after reading directly from disk. The [[#HashMaps|context above]] is to minimize unpredictability.&lt;br /&gt;
&lt;br /&gt;
To set a &#039;&#039;HashMap&#039;&#039;, a &#039;&#039;ConfigurationSection&#039;&#039; must be created for that HashMap. You can only set HashMap where the key is a string the the value is something that is ConfigurationSerializable. The createSectionMethod &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.getConfig().createSection(String path, Map&amp;lt; String, Object &amp;gt; map)&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 保存文件 ===&lt;br /&gt;
&lt;br /&gt;
如果你对一个 &#039;&#039;FileConfiguration&#039;&#039; 对象进行了修改操作，或者改变了某些 &#039;&#039;Lists&#039;&#039;，如果你想保存你的修改，让插件被卸载了这些数据也能得以保存的话，你可以把你修改的数据保存到硬盘里。保存文件到硬盘里，你可以借助 saveConfig 方法。这会重写硬盘里的那份配置文件。 &amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.saveConfig();&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 从磁盘中重载配置文件 ===&lt;br /&gt;
&lt;br /&gt;
如果你怀疑用户在插件数据文件夹里修改了&#039;&#039;config.yml&#039;&#039;，并且那些数据并没有更新在内存里。你可以用 &#039;&#039;reloadConfig()&#039;&#039; 方法重新读取插件文件夹中最新的配置文件信息，来更新内存中的数据，但这会把你内存中保存的那份数据删除，这可能会让你丢失一部分数据。 &amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;this.reloadConfig();&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 高级  ==&lt;br /&gt;
&lt;br /&gt;
The following are some more advanced topics, meant for more advanced plugins. If you only require the default &#039;&#039;config.yml&#039;&#039;, creating custom methods for reading, and saving, you will not need to go this far. &lt;br /&gt;
&lt;br /&gt;
=== 菜单  ===&lt;br /&gt;
&lt;br /&gt;
Every &#039;&#039;FileConfiguration&#039;&#039; instance is associated with a [http://jd.bukkit.org/apidocs/index.html?org/bukkit/configuration/file/FileConfigurationOptions.html FileConfigurationOptions] object. The &#039;&#039;FileConfigurationOptions&#039;&#039; object controls the behavior of the &#039;&#039;FileConfiguration&#039;&#039; it is associated with. &#039;&#039;FileConfiguration&#039;&#039;&#039;s &#039;&#039;options()&#039;&#039; method returns the &#039;&#039;FileConfigurationOption&#039;s&#039;&#039; responsible for it. With it you can check and set each option. There are currently four options. Be aware that the methods are overloaded, for example &#039;&#039;copyDefaults()&#039;&#039; which returns a boolean and &#039;&#039;copyDefaults(boolean)&#039;&#039; which returns it self, but has a side effect which changes the state. &lt;br /&gt;
&lt;br /&gt;
==== CopyDefaults  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;copyDefaults&#039;&#039; option changes the behavior of Configuration&#039;s save method. By default, the defaults of the configuration will not be written to the target save file. If set to true, it will write out the default values, to the target file. However, once written, you will not be able to tell the difference between a default and a value from the configuration. &lt;br /&gt;
&lt;br /&gt;
==== PathSeperator  ====&lt;br /&gt;
&lt;br /&gt;
PathSeperator changes the character that is used to separate the different levels of the configuration. By default it is the &amp;quot;.&amp;quot; (period) but it can be changed to any char. &lt;br /&gt;
&lt;br /&gt;
==== Header  ====&lt;br /&gt;
&lt;br /&gt;
Header is the comment block at the top of a YAML file, it is applied to the save output. The header is the only comment that Configuration API knows how to copy. &lt;br /&gt;
&lt;br /&gt;
==== copyHeader  ====&lt;br /&gt;
&lt;br /&gt;
If &#039;&#039;copyHeader()&#039;&#039; returns true then the header will be copied on save, from the default source. &lt;br /&gt;
&lt;br /&gt;
=== 自定义配置文件  ===&lt;br /&gt;
&lt;br /&gt;
如果你需要额外的YAML文件来存储其他的配置信息，或储存额外的游戏信息配置文件等，你可以自己写一个你自己的方法，来仿照 &amp;lt;big&amp;gt;JavaPlugin&amp;lt;/big&amp;gt; 类里的 getConfig，reloadConfig，saveConfig 方法实现这一目的。下面是一个例子，可以告诉你如何编写一个方法，来读取和保存自定义配置文件。由于这些配置文件属于你的插件，你可以把这个方法放在你的主类，这样用起来跟原来一样。你必须为每个YAML文件写的一套方法。不过你可以使用以相同的方式设置为默认设置的方法config.yml 。另外，添加额外的方法可以保持较低的计数方法，并允许访问多个文件。&lt;br /&gt;
&lt;br /&gt;
==== JavaPlugin 镜像的实现 ====&lt;br /&gt;
javaplugin实现方法config.yml。插件需要实现它自己的方法来访问插件的配置文件。实现插件的方法后，就可以调用相同的上下文中的继承”getconfig() &#039;、&#039; reloadconfig() &#039;、&#039; saveconfig() &#039;，和&#039; savedefaultconfig()”方法javaplugin。以下可以做成一个类可以访问任何YAML文件。这样一个类可以在这里找到：&lt;br /&gt;
&lt;br /&gt;
[https://gist.github.com/3174347 ClickHere]&lt;br /&gt;
&lt;br /&gt;
首先，您需要声明2个字段，并将其初始化为每个自定义配置文件空值。一个“&#039;fileconfiguration”对象和一个&amp;quot;file‘’的对象。file对象表示磁盘上的文件，和fileconfiguration代表配置的内容。&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private FileConfiguration customConfig = null;&lt;br /&gt;
private File customConfigFile = null;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 实现重载 =====&lt;br /&gt;
然后，你写的方法负责从磁盘加载配置。它将加载文件和搜索位于jar里的默认customconfig.yml    。&lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void reloadCustomConfig() {&lt;br /&gt;
    if (customConfigFile == null) {&lt;br /&gt;
    customConfigFile = new File(getDataFolder(), &amp;quot;customConfig.yml&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    customConfig = YamlConfiguration.loadConfiguration(customConfigFile);&lt;br /&gt;
&lt;br /&gt;
    // Look for defaults in the jar&lt;br /&gt;
    Reader defConfigStream = new InputStreamReader(this.getResource(&amp;quot;customConfig.yml&amp;quot;), &amp;quot;UTF8&amp;quot;);&lt;br /&gt;
    if (defConfigStream != null) {&lt;br /&gt;
        YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);&lt;br /&gt;
        customConfig.setDefaults(defConfig);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== 实现获取 =====&lt;br /&gt;
Next, you need to write the getter method. Check if &#039;&#039;customConfig&#039;&#039; is null, if it is load from disk. &lt;br /&gt;
接下来，您需要编写getter方法。如果customconfig是从磁盘加载，请检查它是否为null。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public FileConfiguration getCustomConfig() {&lt;br /&gt;
    if (customConfig == null) {&lt;br /&gt;
        reloadCustomConfig();&lt;br /&gt;
    }&lt;br /&gt;
    return customConfig;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 实现保存 =====&lt;br /&gt;
&lt;br /&gt;
Finally, write the save method, which saves changes and overwrites the file on disk. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void saveCustomConfig() {&lt;br /&gt;
    if (customConfig == null || customConfigFile == null) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    try {&lt;br /&gt;
        getCustomConfig().save(customConfigFile);&lt;br /&gt;
    } catch (IOException ex) {&lt;br /&gt;
        getLogger().log(Level.SEVERE, &amp;quot;Could not save config to &amp;quot; + customConfigFile, ex);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 实施默认覆盖 =====&lt;br /&gt;
Optionally, you may want to write a method that mimics JavaPlugin&#039;s saveDefaultConfig() method.  &lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void saveDefaultConfig() {&lt;br /&gt;
    if (customConfigFile == null) {&lt;br /&gt;
        customConfigFile = new File(getDataFolder(), &amp;quot;customConfig.yml&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (!customConfigFile.exists()) {            &lt;br /&gt;
         plugin.saveResource(&amp;quot;customConfig.yml&amp;quot;, false);&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 序列化与反序列化对象  ===&lt;br /&gt;
&lt;br /&gt;
在 Configuration API 中，上面提及的可以存储的对象均实现（implements）了 &#039;&#039;ConfigurationSerializable&#039;&#039; 接口。 对象序列化可以有助我们保存和读取数据，来让插件开发者集中开发插件的其他部分。 它真正的使一些任务变得简单明了了，就例如存储一个 &#039;&#039;[http://jd.bukkit.org/doxygen/da/dac/classorg_1_1bukkit_1_1Location.html Location]&#039;&#039; 对象到YAML文件当中， 开发者可以序列化一个包装类，用以提供取用 &#039;&#039;Location&#039;&#039; 对象的方法。&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Classes, 除了implementing the &#039;&#039;ConfigurationSerializable&#039;&#039; interface must also implment one of the following as noted in the Javadoc, so that they can be serialized by the API: &lt;br /&gt;
&lt;br /&gt;
*A constructor that accepts a single &#039;&#039;Map&#039;&#039;. &lt;br /&gt;
*A static method &amp;quot;deserialize&amp;quot; that accepts a single &#039;&#039;Map&#039;&#039; and returns the class. &lt;br /&gt;
*A static method &amp;quot;valueOf&amp;quot; that accepts a single Map and returns the class.&lt;br /&gt;
&lt;br /&gt;
In order for a serialized object to be deserialized, it must also be registered with ConfigurationSerialization. The static registerClass method must be invoked once per class that has been serialized.&lt;br /&gt;
&lt;br /&gt;
This statement must be placed in your onEnable method or some other location that gets called every time your plugin is initialized:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;ConfigurationSerialization.registerClass(Class&amp;lt;? extends ConfigurationSerializable&amp;gt;)&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{{warning}}Do not use a static block to execute the above; if you do so, it will not be called a second time when &amp;lt;code&amp;gt;/reload&amp;lt;/code&amp;gt; is used and you will encounter errors due to it not being registered!&lt;br /&gt;
&lt;br /&gt;
==== Aliases  ====&lt;br /&gt;
&lt;br /&gt;
When classes are serialized they are marked with their fully qualified name.&lt;br /&gt;
You can provide an alias to your class so that it does not serialize with the fully qualified name of your class, but the alias instead. You provide the alias with the &#039;&#039;SerializableAs&#039;&#039; annotation to the class implementing &#039;&#039;ConfigurationSerializable&#039;&#039;. &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;@SerializableAs(String)&amp;lt;/source&amp;gt; When registering a class with an alias, the alias must be provided on registration. &amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;ConfigurationSerialization.registerClass(Class&amp;lt;? extends ConfigurationSerializable&amp;gt;, String)&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 使用样例 ==&lt;br /&gt;
&lt;br /&gt;
下面是一个使用了新版Configuration API的样例插件，它可以显示MOTD信息给进入服务器的玩家，并且可以让玩家使用指令获取规则（rule）。&#039;&#039;此处为了让代码行数达到最佳，代码没有采用适当的风格和插件布局&#039;&#039;。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;import java.util.*;&lt;br /&gt;
import org.bukkit.command.*;&lt;br /&gt;
import org.bukkit.event.*;&lt;br /&gt;
import org.bukkit.plugin.java.JavaPlugin;&lt;br /&gt;
import org.bukkit.configuration.file.FileConfiguration;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class SimpleMOTD extends JavaPlugin {&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onEnable() {&lt;br /&gt;
        // 如果没有默认 config.yml 文件，保存一个默认配置副本&lt;br /&gt;
        this.saveDefaultConfig();&lt;br /&gt;
        &lt;br /&gt;
        // 注册新的监听器&lt;br /&gt;
        getServer().getPluginManager().registerEvents(new Listener() {&lt;br /&gt;
            &lt;br /&gt;
            @EventHandler&lt;br /&gt;
            public void playerJoin(PlayerJoinEvent event) {&lt;br /&gt;
                // 当玩家进入服务器时发送 config.yml 文件里的信息&lt;br /&gt;
                event.getPlayer().sendMessage(this.getConfig().getString(&amp;quot;message&amp;quot;));&lt;br /&gt;
            }&lt;br /&gt;
        }, this);&lt;br /&gt;
&lt;br /&gt;
        // 给获取规则指令（rules）设置命令执行器（Command Executor）&lt;br /&gt;
        this.getCommand(&amp;quot;rules&amp;quot;).setExecutor(new CommandExecutor() {&lt;br /&gt;
            &lt;br /&gt;
            public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {&lt;br /&gt;
                // 当指令被执行，发送 config.yml 里的规则信息给输入指令的人&lt;br /&gt;
                List&amp;lt;String&amp;gt; rules = this.getConfig().getStringList(&amp;quot;rules&amp;quot;);&lt;br /&gt;
                for (String s : rules){&lt;br /&gt;
                    sender.sendMessage(s);&lt;br /&gt;
                }&lt;br /&gt;
                return true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt; 插件jar文件中的默认 config.yml 文件&lt;br /&gt;
&amp;lt;source lang=&amp;quot;yaml&amp;quot;&amp;gt;# default config.yml&lt;br /&gt;
message: Hello World and Welcome! :)&lt;br /&gt;
rules:&lt;br /&gt;
  - Play Nice&lt;br /&gt;
  - Respect others&lt;br /&gt;
  - Have Fun&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>1216500866</name></author>
	</entry>
</feed>