You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java接口无法实例化却能运行?解析背后实现原理

关于Java接口类型变量与Spring松耦合的疑问

我在学习Spring松耦合特性时遇到一个困惑:理论上Java接口无法被实例化,但我接触到一段代码,其中GameRunner类中定义了private GamingConsole game;这样的接口类型变量,且代码能够正常运行。相关代码如下:

定义的接口

public interface GamingConsole {
    void up();
    void down();
    void left();
    void right();
}

包含接口变量的GameRunner类

public class GameRunner {
    private GamingConsole game;  // 我以为这里是在实例化接口

    public GameRunner(GamingConsole game) {
        this.game = game;
    }
    public void run() {
        System.out.println("Running Game" + game);
        game.up();
        game.down();
        game.left();
        game.right();
    }
}

调用类

public class AppGamingBasicJava {

    public static void main(String[] args) {
        // var game = new MarioGame();
        // var game = new SuperContraGame();
        var game = new PacManGame();
        var gameRunner = new GameRunner(game);
        gameRunner.run();
    }

}

我想知道这段代码实际在做什么,为何看似实例化接口却能正常运行,以及代码的具体运行机制。


解答

  1. 变量声明≠实例化
    private GamingConsole game;只是声明了一个接口类型的变量,并没有实例化接口。接口类型的变量相当于一个"通用引用",它可以指向任何实现了该接口的具体类实例,这是Java多态特性的核心用法。

  2. 真正的实例化在调用类中
    AppGamingBasicJava的main方法里,var game = new PacManGame();才是实例化操作——PacManGame必然是实现了GamingConsole接口的具体类(它会重写接口中所有抽象方法)。这个具体类的实例被赋值给GamingConsole类型变量,完全符合Java的多态规则。

  3. GameRunner的执行逻辑
    当把PacManGame实例传入GameRunner的构造方法后,GameRunner中的game变量就指向了这个具体实例。调用gameRunner.run()时,实际执行的是PacManGame中重写的up()、down()等方法,接口本身没有方法实现,不会被执行。

  4. 松耦合的核心体现
    GameRunner只依赖GamingConsole这个抽象接口,不关心具体是哪个游戏类。不管是换成MarioGame还是新增其他实现了接口的游戏类,都不需要修改GameRunner的代码,这就是Spring松耦合特性的基础——依赖抽象而非具体实现,大幅提升代码的扩展性和可维护性。

内容的提问来源于stack exchange,提问作者Jitin Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:25:01