接口(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 就是典型的"实例常量"------每个对象有自己的值,且创建后不可变。

相关推荐
舒一笑3 小时前
利用Mybatis自定义排序规则实现复杂排序
后端·排序算法·mybatis
毕设源码-郭学长4 小时前
【开题答辩全过程】以 基于vue+springboot的校园疫情管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
中国lanwp4 小时前
Tomcat 中部署 Web 应用
java·前端·tomcat
Joey_Chen4 小时前
【Golang开发】快速入门Go——Goroutine和Channel
后端·go
岁忧4 小时前
(LeetCode 每日一题) 36. 有效的数独 (数组、哈希表)
java·c++·算法·leetcode·go·散列表
JNNarrator4 小时前
4.JVM对象创建与内存分配机制
java
失散134 小时前
并发编程——11 并发容器(Map、List、Set)实战及其原理分析
java·架构·并发编程
CF14年老兵4 小时前
努力生活,本身就是一种成就
前端·后端·trae
LSTM974 小时前
Python与Excel的华丽邂逅:用Spire.XLS for Python高效读取数据
后端