2023-03-19  阅读(5)
原文作者:简单教程 原文地址: https://www.twle.cn/c/yufei/java9/java9-basic-intro.html

在我的印象中,好像,从来没有,想过在 interface 中定义私有的方法。一来各种文档中的确没有这么介绍过,二来,好像从来没有谁这么做过,三来,好像定义了也不知道要怎么使用,毕竟,接口 interface 中的方法都会被具体的类重写一次,所以,似乎,私有方法都没啥大作用了。

比如说,很简单的,我们的 Java 基础教程: Java 接口 中,就没有论述私有方法这回事。

既然 Java 9 添加了这项特性,那么,应该就有它的用途,我们一起来看看 Java 9 中的接口的私有方法是什么样的吧。

JDK 7 / JDK 6

回忆一下,Java 8 之前 ,接口好像就只允许两种类型的数据,一个是常量、另一个就是公开 ( public ) 的虚方法 ( abstract ),而且是虚方法哦,就是没有任何实现的方法,因为这些方法要被类来实现。

也就是说,Java 8 之前的版本不存在有着默认实现的方法

我们来看看一个示例,在我们的工作区创建一个文件 InterfacePrivateMethodTester.java ,并输入一下内容

    public class InterfacePrivateMethodTester {
    
       public static void main(String []args) {
          LogOracle log = new LogOracle();
          log.logInfo("");
          log.logWarn("");
          log.logError("");
          log.logFatal("");
          LogMySql log1 = new LogMySql();
          log1.logInfo("");
          log1.logWarn("");
          log1.logError("");
          log1.logFatal("");
       }
    }
    
    
    final class LogOracle implements Logging {
    
       @Override
       public void logInfo(String message) {
          getConnection();
          System.out.println("Log Message : " + "INFO");
          closeConnection();
       }
       @Override
       public void logWarn(String message) {
          getConnection();
          System.out.println("Log Message : " + "WARN");
          closeConnection();
       }
       @Override
       public void logError(String message) {
          getConnection();
          System.out.println("Log Message : " + "ERROR");
          closeConnection();
       }
       @Override
       public void logFatal(String message) {
          getConnection();
          System.out.println("Log Message : " + "FATAL");
          closeConnection();
       }
       @Override
       public void getConnection() {
          System.out.println("Open Database connection");
       }
       @Override
       public void closeConnection() {
          System.out.println("Close Database connection");
       }
    }
    
    
    final class LogMySql implements Logging {
    
       @Override
       public void logInfo(String message) {
          getConnection();
          System.out.println("Log Message : " + "INFO");
          closeConnection();
       }
       @Override
       public void logWarn(String message) {
          getConnection();
          System.out.println("Log Message : " + "WARN");
          closeConnection();
       }
       @Override
       public void logError(String message) {
          getConnection();
          System.out.println("Log Message : " + "ERROR");
          closeConnection();
       }
       @Override
       public void logFatal(String message) {
          getConnection();
          System.out.println("Log Message : " + "FATAL");
          closeConnection();
       }
       @Override
       public void getConnection() {
          System.out.println("Open Database connection");
       }
       @Override
       public void closeConnection() {
          System.out.println("Close Database connection");
       }
    }
    
    
    interface Logging {
       String ORACLE = "Oracle_Database";
       String MYSQL = "MySql_Database";
    
       void logInfo(String message);
       void logWarn(String message);
       void logError(String message);
       void logFatal(String message);
    
       void getConnection();
       void closeConnection();
    }

运行结果如下

    [yufei@www.twle.cn java9]$ javac InterfacePrivateMethodTester.java && java InterfacePrivateMethodTester
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection

在这个实例中,每种类型的日志都有自己的实现

最坑的是什么,每个方法都要实现一遍。是的,每个方法都要实现

JDK 8

而 Java 8 也终于作出了一些改变,Java 8 中的接口,可以具有以下类型的变量和方法

  1. 常量
  2. 虚方法
  3. 默认方法
  4. 静态方法

我们将上面的范例改改,使用 Java 8 的特性

InterfacePrivateMethodTester.java

    public class InterfacePrivateMethodTester {
       public static void main(String []args) {
          LogOracle log = new LogOracle();
          log.logInfo("");
          log.logWarn("");
          log.logError("");
          log.logFatal("");
    
          LogMySql log1 = new LogMySql();
          log1.logInfo("");
          log1.logWarn("");
          log1.logError("");
          log1.logFatal("");
       }
    }
    
    final class LogOracle implements Logging {}
    
    final class LogMySql implements Logging {}
    
    
    interface Logging {
       String ORACLE = "Oracle_Database";
       String MYSQL = "MySql_Database";
    
       default void logInfo(String message) {
          getConnection();
          System.out.println("Log Message : " + "INFO");
          closeConnection();
       }
       default void logWarn(String message) {
          getConnection();
          System.out.println("Log Message : " + "WARN");
          closeConnection();
       }
       default void logError(String message) {
          getConnection();
          System.out.println("Log Message : " + "ERROR");
          closeConnection();
       }
       default void logFatal(String message) {
          getConnection();
          System.out.println("Log Message : " + "FATAL");
          closeConnection();
       }
       static void getConnection() {
          System.out.println("Open Database connection");
       }
       static void closeConnection() {
          System.out.println("Close Database connection");
       }
    }

运行结果如下

    [yufei@www.twle.cn java9]$ javac InterfacePrivateMethodTester.java && java InterfacePrivateMethodTester
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection

因为 Java 8 的接口中的方法可以有默认实现,也就是使用 default 关键字修饰的方法

所以,类实现某个接口就比较简单了,可以有选择性的实现部分方法。

但是,仍然很坑,就是每个默认方法中的代码,都必须完整的,而且不能调用其它的默认实现方法

Java 9

终于忍无可忍了,Java 9 中可以为接口提供私有的方法,包括私有成员方法和私有静态方法

所以 Java 9 中的接口,可以具有以下类型的变量和方法

  1. 常量
  2. 虚方法
  3. 默认方法
  4. 静态方法
  5. 私有静态方法
  6. 私有方法

于是,我们可以继续修改刚刚的实例,改的更简单明白些

InterfacePrivateMethodTester.java

    public class InterfacePrivateMethodTester {
       public static void main(String []args) {
          LogOracle log = new LogOracle();
          log.logInfo("");
          log.logWarn("");
          log.logError("");
          log.logFatal("");
    
          LogMySql log1 = new LogMySql();
          log1.logInfo("");
          log1.logWarn("");
          log1.logError("");
          log1.logFatal("");
       }
    }
    
    final class LogOracle implements Logging {}
    
    final class LogMySql implements Logging {}
    interface Logging {
       String ORACLE = "Oracle_Database";
       String MYSQL = "MySql_Database";
    
       private void log(String message, String prefix) {
          getConnection();
          System.out.println("Log Message : " + prefix);
          closeConnection();
       }
       default void logInfo(String message) {
          log(message, "INFO");
       }
       default void logWarn(String message) {
          log(message, "WARN");
       }
       default void logError(String message) {
          log(message, "ERROR");
       }
       default void logFatal(String message) {
          log(message, "FATAL");
       }
       private static void getConnection() {
          System.out.println("Open Database connection");
       }
       private static void closeConnection() {
          System.out.println("Close Database connection");
       }
    }

运行结果如下

    [yufei@www.twle.cn java9]$ javac InterfacePrivateMethodTester.java && java InterfacePrivateMethodTester
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection
    Open Database connection
    Log Message : INFO
    Close Database connection
    Open Database connection
    Log Message : WARN
    Close Database connection
    Open Database connection
    Log Message : ERROR
    Close Database connection
    Open Database connection
    Log Message : FATAL
    Close Database connection

不容易啊,Java 竟然用了 2 个大的版本才达到了其它语言轻轻松松从创世开始就有的机制


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文