【问题标题】:Java final class with constant具有常量的 Java final 类
【发布时间】:2016-03-01 09:08:12
【问题描述】:

我必须定义一个类,它所做的只是保存常量。

public static final String CODE1 = "100";
public static final String CODE2 = "200";

现在我想在其他类中使用这些值。将此类用作静态类还是实例化它会更好吗?

谢谢。

注意:我知道枚举,但在这种情况下,我必须使用一个类。

【问题讨论】:

  • 由于您的字段是静态的,因此没有理由实例化您的类。你能解释一下为什么枚举不是解决方案,因为它们也是类。
  • 如果你使用静态值,实例化类不会给你带来优势

标签: java class oop static final


【解决方案1】:

只是为了使用这些值,您当然不应该实例化该类。仅仅因为您可以像访问实例成员一样访问静态成员并不意味着这是一个好主意。

如果类真的只包含常量——如果你确定这是一个好主意,而不是那些出现在与它们直接相关的类中的常量——你应该让它成为一个带有私有构造函数的final类,这样没有人可以毫无意义地实例化它:

public final class Codes {
    public static final String CODE1 = "100";
    public static final String CODE2 = "200";

    // Prevent instantiation
    private Codes() {
    }
}

Don 的回答建议使用枚举也是一个非常好的主意 - 这意味着您可以在您的 API 中使用Code 在您不需要需要确切字符串表示的任何地方,这会阻止您不小心使用了非代码值。

【讨论】:

  • 我们不能用反射来实例化它吗?
  • @Kartic: 只打电话给setAccessible 或其他什么...它不会造成任何伤害,它只是不打算被建造。如果人们想滥用反射,并且他们在允许他们这样做的安全管理器中运行,那么就没有太多工作要做。
  • @Kartic throw new UnsupportedOperationException() 在构造函数中也会阻止反射实例化。
  • @Dragan Bozanovic 是的!我同意。
【解决方案2】:

Jons 的回答是正确的,尽管我想向您展示一个带有枚举的解决方案。 访问它的 String 值有一个缺点,因为您必须调用 Code.CODE1.text() 而不是 Code.CODE1

public enum Code {

    CODE1("100"), CODE2("200");

    private String text;

    Codes(String text) {
        this.text = text;
    }

    public String text() {
        return text;
    }
}

【讨论】:

  • 我将其称为Code 而不是Codes,这样您就可以在采用单个Code... 的API 中使用它,并且可能将属性重命名为getText() 或类似,但这是小事:)
  • 我想坚持你的答案,因此我使用了Codes,甚至没有考虑过命名。但你是对的,我会重命名它。我还考虑过覆盖toString() 以返回code,但我不想失去返回枚举名称的优势。我个人不喜欢 getX()methods 的枚举,所以我会选择 text()
  • 唐,当您更新代码时,请检查您是否在答案中的其他地方使用了该代码并修复这些地方。请检查我的编辑,看看你错过了什么。
【解决方案3】:

java 语言规范和 JVM 规范允许你做任何你想做的事情,无论是实例化一个类还是使用 final 或使用其他方式......

只需使用 Eclipse 并尝试!

虽然有一些好的做法,但 Jon Skeet 的回答是一种好的做法。

【讨论】:

    【解决方案4】:

    Java 语言不支持全局变量

    public class ComonFun {
        public static final String CODE1 = "100";
        public static final String CODE2 = "200";
    
        public static String CODE1(){
            return CODE1;
        }
        public static String CODE2(){
            return CODE2;
        }
    }
    

    实现

    public class Main {
    
        public static void main(String[] args) {
            System.out.println(ComonFun.CODE1());
            System.out.println(ComonFun.CODE2());
        }
    }
    

    【讨论】:

    • Java 内置函数 Math...示例 Math.PI
    • 为公共静态字段编写 getter 的原因是什么?您可以在没有 getter 的情况下访问它们。另外,由于您在方法中使用大写字母,因此您的命名违反了约定。
    【解决方案5】:

    我认为您只需要声明一个接口,就不需要指定“public static final”子句。并且可以通过大厅项目使用。

    【讨论】:

      【解决方案6】:

      将它们用作静态,不要用于实例化。

      甚至使用静态导入作为一个好处。

      package coma;
      
      import static coma.ImportStatments.*;
      
      public class UsingClass {
          public static void main(String[] args) {
              System.out.println(CODE1);
          }
      }
      

      带有最终变量的类看起来像这样:

      package coma; 
      public class ImportStatments {  
          public static final String CODE1 = "100";   
          public static final String CODE2 = "200"; 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-21
        • 1970-01-01
        • 2013-07-04
        • 2016-10-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多