Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个接口是如何实例化的?_Java_Interface_Minecraft - Fatal编程技术网

Java 这个接口是如何实例化的?

Java 这个接口是如何实例化的?,java,interface,minecraft,Java,Interface,Minecraft,这是来自Minecraft服务器的源代码,也称为Minecraft Bukkit API,现在你和我一样了解 有一个称为服务器的接口: public interface Server extends PluginMessegeRecipient { public String getVersion(); } PluginMessageRecipient也是一个接口 有一个名为Bukkit的类实例化服务器: public final class Bukkit { private

这是来自Minecraft服务器的源代码,也称为Minecraft Bukkit API,现在你和我一样了解

有一个称为服务器的接口:

public interface Server extends PluginMessegeRecipient {
    public String getVersion();
}
PluginMessageRecipient也是一个接口

有一个名为Bukkit的类实例化服务器:

public final class Bukkit {
    private static Server server;

}
在Bucket类中的方法内部,它们从服务器对象调用方法。例如:

server.getVersion();
问题是,服务器接口中没有getVersion的代码,只有一个方法签名。PluginMessageRecipient接口中也没有代码,也没有扩展任何内容

我已经阅读了上面的所有问题和答案,所以说我需要一个匿名类或内部类,而这似乎不适合这些解决方案

有一个名为
Bucket
的类实例化服务器:

public final class Bukkit {
    private static Server server;

}
实际上
Bucket
并没有实例化
Server
。类
Bucket
包含对
服务器的引用。你还没有展示它是如何设置的,所以我们不知道实际的类


但是,可以保证分配给该引用(
Bucket.server
)的对象(假设它不是
null
)是实现
server
的某个具体类的对象。该类将提供一个
getVersion()
的实现,这就是所调用的。

Bukkit只是一个修改API。如果您想要实现Bukkit,您需要自己创建这样一个实例并将其传递给它

以Bukkit包括的单元测试为例:


允许您运行Bukkit服务器的真正实现是spiget。

如果我没记错的话,正在选择的特定具体类是在运行时通过反射确定的。因为Minecraft不是开源的,所以开发人员所拥有的都是经过模糊处理的编译类文件

代码搜索minecraft jar中的每个类文件,搜索符合特定条件的类,然后使用字节码库强制该类实现该接口

例如,假设以下(模糊)类是Minecraft代码中真正的
Server

class a {

    String x_x317() {
        return q_q98;
    }

    static a a_a1;
    static String q_q98 = "1.9.4";
}
在本例中,方法
x_x317
返回版本字符串。允许它们也钩住此类的工具可能会基于以下条件执行此操作:

  • 该类具有默认访问权限
  • 该类只有一个对自身的默认访问静态引用
  • 该类只有一个默认的访问静态字符串字段
  • 该类有一个具有默认访问权限的方法,该方法返回
    String
    ,返回的值是在3中找到的
    FieldRef
  • 这通常只返回一个类。在返回多个类的情况下(通常在新Bukkit版本的开发阶段),它们的条件更加具体,以确保只返回正确的类。他们对需要识别的每个字段、类和方法都这样做

    因为他们现在知道哪个类是
    服务器
    类,所以可以继续对其进行更改。首先,他们需要实现接口

    class a implements org.bukkit.Server
    
    然后实现该方法

    class a implements org.bukkit.Server {
    
        String x_x317() {
            return q_q98;
        }
    
        public String getVersionNumber() {
            return x_x317();
        }
    
        static a a_a1;
        static String q_q98 = "1.9.4";
    }
    
    现在,我们有了一个符合BukkitAPI的类

    当他们需要实例化那个类时,他们只是按照

    Server server = findAndTransformServerClassFromMinecraftJar();
    
    // ...
    
    Server findAndTransformServerClassFromMinecraftJar() {
        // load classes from jar
        // map them to the appropriate interfaces
        // transform and hook the required classes and methods
    
        Class<?> serverClass = doTheFirstThreeSteps();
    
        return (Server) serverClass.newInstance();
    }
    
    Server-Server=findAndTransformServerClassFromMinecraftJar();
    // ...
    服务器FindTransformServerClassFromMineCraftjar(){
    //从jar加载类
    //将它们映射到适当的接口
    //转换并钩住所需的类和方法
    Class serverClass=doTheFirstThreeSteps();
    返回(服务器)serverClass.newInstance();
    }
    
    我怀疑
    server
    在某个时候被实例化为
    server
    接口的一个实现类。例如:
    Bucket.server=newversionfiveserver()
    VersionFiveServer实现了server
    。服务器是一个接口,因此它没有代码。它将只具有方法签名。这就是接口。其他一些类将实现该接口并包含代码。相关:@CollinD所以你认为有一个名为Server的类和一个名为Sever的接口?你是说Bukkit?!因为这就是代码的来源,我不知道MC的任何“Bucket API”。“Bucket类包含一个对服务器的引用。你没有展示它是如何设置的,所以我们不知道实际的类。”——没有。我不能展示它。这是我的问题。它被设定在某个地方,所以“没有一个”在脸上是假的。你说它是一个API,所以毫无疑问,在某个地方有一个调用,或者在某个地方有一个配置文件(XML、JSON、属性等等),或者在某个地方有一个命令行选项,再加上某个地方的某种初始化代码,指定了实现类。你只是还没有找到它。你试过API的文档了吗?实际上,bukkit是在一个已经除臭的jar上工作的(并且有一个具体的实现,
    CraftServer
    ,它是定制的,尽管CraftBukkit的其他部分引用了普通代码)