接口(interface)中的常量和 类(class)中的常量的区别

接口(interface)中的常量类(class)中的常量 的区别。

1、定义方式

1.1. 接口中的常量(interface constant)

ini 复制代码
public interface Config {
    // 不需要显式写 public static final
    String NAME = "A**";
    int MAX_COUNT = 100;
}

接口中定义的变量,默认就是 public static final,即使你不写,编译器也会自动加上。

  • public:公开访问
  • static:属于接口本身,不依赖实例
  • final:不可修改

1.2. 类中的常量(class constant)

arduino 复制代码
public class Config {
    // 必须显式声明 static final
    public static final String NAME = "A**";
    public static final int MAX_COUNT = 100;
}

类中必须显式写出 static final,否则就不是常量。

2、核心区别对比

特性 接口中的常量 类中的常量
修饰符是否可选 ✅ 隐式 public static final,可不写 ❌ 必须显式写 static final
访问方式 InterfaceName.CONSTANT ClassName.CONSTANT
是否可以修改 final,不可变 final,不可变
存储位置 方法区(元数据) 方法区(类静态变量)
继承行为 实现类自动继承常量 子类可以继承 public/protected
初始化时机 接口加载时初始化 类加载时初始化
性能 几乎无差别 几乎无差别
使用场景 定义公共配置、协议常量 定义类相关的常量、配置

3、代码示例

示例 1:接口常量的继承

typescript 复制代码
public interface AppConfig {
    String DOMAIN = "XX";
    String TOKEN = "....";
}

public class LoginService implements AppConfig {
    public void connect() {
        System.out.println("域名: " + DOMAIN); // 直接使用接口常量
    }
}

LoginService 虽然没有实现方法,但可以直接使用 DOMAINTOKEN

示例 2:类常量的继承

scala 复制代码
public class AppConfig {
    public static final String ENV = "prod";
}
public class DatabaseConfig extends AppConfig {
    public void printEnv() {
        System.out.println("环境: " + ENV); // 继承父类常量
    }
}

类通过继承获得常量。

4、注意:

1. 接口常量是"隐式 public static final"

ini 复制代码
interface BadExample {
    final String NAME = "Alice";        // ❌ 冗余,final 可省略
    static int COUNT = 10;              // ❌ 冗余
    // private String SECRET = "...";   // ❌ 编译错误!接口常量必须是 public
}

2. 接口不能有"实例常量"

  • 不能有实例变量和实例常量(包括常量)
  • 所有字段必须是 public static final(即:类常量)
  • 接口不能被实例化,所以"实例"相关的概念都不存在
java 复制代码
interface BadExample {
    final String name = "Alice"; // ✅ 可以,但它是 static final(接口常量)
    
    // String instanceValue; // ❌ 错误!接口不能有实例变量
}

3. 接口常量会类常量必须在声明时初始化(因为final修饰)

ini 复制代码
interface Config {
    // String NAME; // ❌ 编译错误!必须赋值
    String NAME = "Alice"; // ✅
}

5、使用建议

场景 推荐方式
定义一组公共配置(如 API 地址、状态码) ✅ 使用 interface 常量(简洁)
常量与某个类强相关(如 Math.PI ✅ 使用 class 常量
常量需要封装逻辑(如通过方法计算) ✅ 使用 class + 私有构造

6、什么是"实例常量"?

"实例常量"指的是:

  • 使用 final 修饰的成员变量
  • 属于对象实例(而不是类)
  • 每个对象可以有不同的值
  • 一旦创建后不可修改

示例:定义实例常量

arduino 复制代码
public class Person {
    // 实例常量:每个 Person 对象都有自己的 name 和 id
    private final String name;
    private final long id;

    // 构造函数中初始化
    public Person(String name, long id) {
        this.name = name;
        this.id = id;
    }

    // 只有 getter,没有 setter(因为是常量)
    public String getName() {
        return name;
    }

    public long getId() {
        return id;
    }
}

使用:

ini 复制代码
Person p1 = new Person("Alice", 1L);
Person p2 = new Person("Bob", 2L);

// p1.name = "Charlie"; // ❌ 编译错误!不能修改 final 变量

nameid 就是典型的"实例常量"------每个对象有自己的值,且创建后不可变。

相关推荐
韩立学长21 小时前
【开题答辩实录分享】以《自助游网站的设计与实现》为例进行选题答辩实录分享
java·mysql·spring
ss27321 小时前
线程池:任务队列、工作线程与生命周期管理
java·后端
不像程序员的程序媛21 小时前
Spring的cacheEvict
java·后端·spring
SAP小崔说事儿21 小时前
在数据库中将字符串拆分成表单(SQL和HANA版本)
java·数据库·sql·sap·hana·字符串拆分·无锡sap
凌云若寒21 小时前
半导体代加工企业标签模板痛点的全景式解决方案
java
踏浪无痕21 小时前
JobFlow 实战:无锁调度是怎么做到的
后端·面试·架构
shoubepatien21 小时前
JAVA -- 11
java·后端·intellij-idea
喵个咪1 天前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:kratos-bootstrap 入门教程(类比 Spring Boot)
后端·微服务·go
利剑 -~1 天前
jdk源码解析
java·开发语言
uzong1 天前
从大厂毕业后,到小公司当管理,十年互联网老兵的思维习惯阶段复盘
后端