【问题标题】:Function with same name and parameter class name (but different parameter classes)具有相同名称和参数类名称的函数(但不同的参数类)
【发布时间】:2019-06-07 19:02:33
【问题描述】:

我遇到了一个非常奇怪的问题,我什至不知道我是否被允许这样做。

基本上我有两个函数,它们应该具有相同的名称,但得到具有相同名称的不同参数对象。

这是因为我想为游戏 Minecraft 写一个插件,它应该与 BungeeCord Bukkit 服务器兼容。

public static void sendMessage(org.bukkit.command.CommandSender p, String k, Object...i){
    //fancy stuff
}

public static void sendMessage(net.md_5.bungee.api.CommandSender p, String k, Object...i){
    //fancy stuff
}

如果插件是由 Bukkit 服务器加载的,那么插件对net.md_5.bungee.api.CommandSender 一无所知,因为这是 BungeeCord 服务器核心的一个类,并且org.bukkit.command.CommandSender 也是如此,它被 Bukkit 使用,但不被 BungeeCore 使用。

我用 IntellIJ 编译代码没有问题,即使面团我有点怀疑,因为如果反编译它看起来像这样:

import org.bukkit.command.CommandSender;

public static void sendMessage(CommandSender p, String k, Object...i){
    //fancy stuff
}

public static void sendMessage(net.md_5.bungee.api.CommandSender p, String k, Object...i){
    //fancy stuff
}

我的第一个问题是:我什至可以这样做吗,或者这是否会产生异常,因为并非所有类都已加载,即使是面团也永远不会被访问?

现在如果Sure you can 可以回答第一个问题,那么为什么使用sendMessage( 函数编译Bukkit 或BungeeCord 插件会出现编译问题?

Bukkit:

BungeeCord:

因为如果这不起作用,我确信您至少可以使用未加载的类,如果您将它们放入您的代码块中,因为此代码可以正常工作,甚至不会抛出异常由使用 org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer 的服务器加载,虽然它在导入中:

import org.bukkit.entity.Player;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;

public static int getPing(Player p) {
    String version = getVersion(instance.getServer());
    if (version.startsWith("v1_8")) {
        return ((org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer)p).getHandle().playerConnection.player.ping;
    } else if (version.startsWith("v1_9")) {
        return ((org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer)p).getHandle().playerConnection.player.ping;
    } else if (version.startsWith("v1_10")) {
        return ((org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer)p).getHandle().playerConnection.player.ping;
    } else if (version.startsWith("v1_11")) {
        return ((org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer)p).getHandle().playerConnection.player.ping;
    } else if (version.startsWith("v1_12")) {
        return ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer)p).getHandle().playerConnection.player.ping;
    } else {
        return ((CraftPlayer)p).getHandle().playerConnection.player.ping;
    }
}

所以这真的是我无法做到的事情,还是 IntellIJ 编译器的问题,如果是,我该如何解决?

【问题讨论】:

  • 是的。如果反编译,例如在 Bukkt 版本 1.10.2 中甚至没有文件夹 v1_13_R2
  • 您确定其他模组不包含给定的 CarftPlazyer 类?也许作为存根?也许在图书馆? 正常类加载需要所有引用的类,不确定Bukkit或Forge是否使用自己的类加载器。
  • 反编译的意义不大,是用户指定反编译的内容和位置

标签: java overloading bukkit


【解决方案1】:

好吧,我对您的想法的尝试是在子类中调用方法。未找到的类是参数可能是一个问题。当访问类时(只是我的推测),会尝试加载参数以确定要使用的方法。

所以输出如下。

在您访问的课程中:

public static void sendMessage(Object player, String k, Object...i){
    if(isBukkit())
        MyBukkitUtils.sendMessage(player, k, i);
    else
        MyBungeeUtils.sendMessage(player, k, i);
}

MyBukkitUtils:

public static void sendMessage(Object player, String k, Object...i){
    if(!(player instanceOf CommandSender))
        return;
    CommandSender p = (CommandSender) player;
    //fancy stuff
}

MyBungeeUtils 也一样,只是使用 BungeeCommandSender。

我不知道您的代码,但如果您必须将所有内容分开,您可以编写两个插件(一个用于插口,一个用于蹦极)并在两个插件中使用包含一个库,以放置公共代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    相关资源
    最近更新 更多