Функция с тем же именем и именем класса параметров (но с разными классами параметров) - PullRequest
1 голос
/ 07 июня 2019

Я столкнулся с очень странной проблемой, которую даже не знаю, разрешено ли мне это делать.

По сути, у меня есть две функции, которые должны иметь одинаковые имена, но получать разные объекты параметров, которые имеютТо же имя.

Это потому, что я хочу написать плагин для игры 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, тогда почему возникает проблема компиляции путем компиляции любого плагина Bukkit или BungeeCord с использованием этой функции sendMessage(?

Bukkit: Bukkit compilation

BungeeCord: enter image description here

Потому что, если это не сработает, я точно знаю, что вы можете по крайней мере работать с классамикоторые не загружаются, если вы помещаете их в кодовый блок, так как этот код работает просто отлично и даже не выдает исключение, когда не загружается сервером, использующим 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, и если да, то как я могу это исправить?

1 Ответ

0 голосов
/ 21 июня 2019

Ну, моя попытка вашей идеи состояла бы в том, чтобы вызывать методы в подклассах. Возможно, проблема в том, что не найденный класс является параметром. Когда к классу обращаются (только мои предположения), параметры пытаются загрузить, чтобы определить, какой метод использовать.

Таким образом, что-то вроде следующего будет выводом.

В классе, к которому у вас есть доступ, есть:

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 только с BunggeeCommandSender.

Я не знаю ваш код, но если вам нужно разделить все, вы можете просто закодировать два плагина (один для spigot, один для bungee) и использовать библиотеку include в обоих, где размещен общий код.

...