这听起来是一个愚蠢的问题。但是,在我使用的API中,版本1.7.2使方法Bukkit.getServer().getOnlinePlayers()
返回Player[]
,版本1.7.10得到Bukkit.getServer().getOnlinePlayers()
返回Collection<Player>
。我需要让我的插件兼容。
我已经获得了两者的API,但除了创建单独的插件外,我目前还不知道如何做到这一点。
我目前只是将集合转换为数组。那么,如果版本低于1.7.9,有没有办法(我已经可以获得版本),不使用.toArray()
但是因为它已经返回了一个数组?
答案 0 :(得分:3)
你可以用反射来做。像这样:
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);
}
}
答案 1 :(得分:2)
实际上有两种方法可以做到这一点。 @ immibis的回答给出了第一种方式。第二种方法涉及创建一个&#34;版本适配器&#34;具有多个插件实现的API,用于不同版本(在本例中)Bukkit; e.g。
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方法调用。
根据上下文,这些可能使适配器方法更合适。
答案 2 :(得分:0)
如果类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();
}
我担心唯一的办法就是像其他人推荐的那样使用反思。
答案 3 :(得分:-1)
你做得很好。不幸的是,没有办法创建可以处理集合和数组的强类型方法。
(您可以创建接受Object
的方法,然后使用instanceof
检查它,转换并处理集合和数组,但这个解决方案很难看。)