![](/img/trans.png)
[英]How do I make JNDI names compatible with both GlassFish and WildFly
[英]How can I make something be compatible with both an array and a collection?
這聽起來是個愚蠢的問題。 但是,在我使用的API中,版本1.7.2的方法Bukkit.getServer().getOnlinePlayers()
返回一個Player[]
,而版本1.7.10的方法將Bukkit.getServer().getOnlinePlayers()
返回一個Collection<Player>
。 我需要使我的插件與兩者兼容。
我都有兩者的API,但是除了創建單獨的插件外,我目前不知道如何執行此操作。
我目前只是將集合轉換為數組。 那么,如果版本小於1.7.9,有什么方法(我已經可以獲取版本)了,不要使用.toArray()
,因為它已經返回了數組?
您可以通過反射來實現。 像這樣:
List<Player> getPlayers() {
try {
Method method = getMethod(Server.class, "getOnlinePlayers");
Object result = method.invoke(Bukkit.getServer());
if(result instanceof Player[])
return Arrays.asList((Player[])result);
else
return (List<Player>)result;
} catch(ReflectiveOperationException e) {
// something went wrong! If you have a better way to handle problems, do that instead
throw new RuntimeException(e);
}
}
實際上有兩種方法可以做到這一點。 @immibis的答案給出了第一種方法。 第二種方法涉及為不同版本的Bukkit(在這種情況下)創建具有多個插件實現的“版本適配器” API。 例如
public interface BukkitVersionAdapter {
Collection<Player> getOnlinePlayers();
...
}
public class BukkitVersionAdapterV1dot7 implements BukkitVersionAdapter {
public Collection<Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getServer().getOnlinePlayers());
}
...
}
public class BukkitVersionAdapterV1dot8 implements BukkitVersionAdapter {
public Collection<Player> getOnlinePlayers() {
return Bukkit.getServer().getOnlinePlayers();
}
...
}
然后,需要針對各個Bukkit版本的Bukkit API jar編譯特定於版本的適配器類。
然后,當您啟動主應用程序(我猜是Bukkit插件)時,您將執行以下操作:
String version = // get the Bukkit version
String className = // map the version to a class name; e.g.
// "pkg.BukkitVersionAdapterV1dot7" or
// "pkg.BukkitVersionAdapterV1dot8"
Class clazz = Class.forName(className);
BukkitVersionAdapter adapter =
(BukkitVersionAdapter) clazz.newInstance();
// Then ...
Collection<Player> players = adapter.getOnlinePlayers();
這都很麻煩,但是與使用反射進行調用的方法相比,它有兩個好處:
現在,針對不同Bukkit版本的特定邏輯已隔離到代碼庫的一部分...而不是分散(潛在地)散布在整個地方。
反射的開銷僅在啟動時發生。 之后,通過適配器API對Bukkit進行的所有方法調用都是常規的Java方法調用。
根據上下文,這些可能會使適配器方法更合適。
如果類org.bukkit.Server
只是更改了方法getOnlinePlayers()
的返回類型,而不是不贊成使用它,而是引入了一個新方法(yack !!!!!誰敢以這種方式更改已發布的接口?) ,您沒有如何在一個代碼中調用該方法的體面方法。 你根本不能寫像
Server server = Bukkit.getServer();
// One of the branches will not be compilable
if (version <= xxxx) {
Player[] players = server.getOnlinePlayers();
}
else {
Collection<Player> players = server.getOnlinePlayers();
}
恐怕唯一的方法就是像其他人推薦的那樣使用反射。
你過得很好 不幸的是,沒有辦法創建可以處理集合和數組的強類型方法。
(您可以創建一個接受Object
方法,然后使用instanceof
進行檢查,強制轉換並處理集合和數組,但是這種解決方案很難看。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.