导入的 Java 类中的公共静态最终变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1693091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:39:10  来源:igfitidea点击:

public static final variable in an imported java class

javastaticfinalpublicrecompile

提问by Senthil Kumar

I happen to come across a Java code at my work place. Here's the scenario: There are 2 classes - ClassAand ClassB.

我碰巧在我的工作场所遇到了 Java 代码。这是场景:有 2 个类 -ClassAClassB.

ClassAhas nothing except 4 public static final string values inside it. Its purpose is to use those values like ClassA.variable(don't ask me why, it's not my code).

ClassA除了内部的 4 个公共静态最终字符串值外,什么都没有。它的目的是使用这些值ClassA.variable(不要问我为什么,这不是我的代码)。

ClassBimports ClassA. I edited the string values in ClassAand compiled it. When I ran ClassBI could see it was using the old values - not the new values. I had to recompile ClassBto make it use new values from ClassA! (I had to recompile other classes that imports ClassA!)

ClassB进口ClassA。我编辑了字符串值ClassA并编译了它。当我运行时,ClassB我可以看到它使用的是旧值 - 而不是新值。我不得不重新编译ClassB以使其使用来自ClassA! (我不得不重新编译其他导入的类ClassA!)

Is this just because of JDK 1.6 or I should have known earlier to recompile ClassBalso! Enlighten me. :)

这只是因为JDK 1.6 还是我早该知道要重新编译ClassB!开导我。:)

采纳答案by Dirk

If the values of the finalvariables from class ClassAhappen to be compile-time constants, the compiler might have inlined them into the classes using ClassAinstead of generating a run-time reference. I think, this is what happened in the case you described.

如果final类中变量的值ClassA恰好是编译时常量,编译器可能会使用ClassA而不是生成运行时引用将它们内联到类中。我想,这就是你描述的情况。

Example:

例子:

public class Flags {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

public class Consumer {
    public static void main(String[] args) {
         System.out.println(Flags.FOO);
    }
}

In this example, the compiler will likely incorporate the value of FOOinto the code generated for Consumerinstead of generating the equivalent run-time reference. If the value of FOOchanges later on, you will have to re-compile Consumerin order to have it use the new value.

在此示例中,编译器可能会将 的值FOO合并到生成的代码中,Consumer而不是生成等效的运行时引用。如果FOO稍后更改的值,您将不得不重新编译Consumer以使其使用新值。

This is an optimization, which has a few advantages with respect to efficiency and speed of the program compiled. For example, inlining the value might enable further optimizations in the expressions, which use it, for example:

这是一种优化,它在编译程序的效率和速度方面具有一些优势。例如,内联该值可能会在使用它的表达式中启用进一步优化,例如:

int x = Flags.FOO * 10;

In this example, inlining the value (here: 1) enables the compiler to notice, that the multiplication makes no difference, and can be omitted alltogether.

在此示例中,内联值(此处为:1)使编译器能够注意到乘法没有区别,并且可以完全省略。

回答by Simon

It's a binary compatibility issue. References to constant fields are resolved at compile time. The behaviour you are seeing is correct; if you change the values in class A then you will have to re-compile the client (class B). To avoid such problems consider adding constants using an enum type, introduced in Java release 5.0.

这是一个二进制兼容性问题。在编译时解析对常量字段的引用。您所看到的行为是正确的;如果更改 A 类中的值,则必须重新编译客户端(B 类)。为避免此类问题,请考虑使用 Java 5.0 版中引入的枚举类型添加常量。

回答by Peter Lawrey

Why are you trying to compile the classes individually?

为什么要单独编译这些类?

Use a build system like maven or ant or just let your IDE do it.

使用像 maven 或 ant 这样的构建系统,或者让你的 IDE 来做。

The only safe thing to do is to recompile every java which depends of a java class which has changed until every class which could be effected has been re-compiled.

唯一安全的做法是重新编译依赖于已更改的 Java 类的每个 Java,直到重新编译每个可能受影响的类。

回答by TofuBeer

If you are not using the values in a switch you can do this instead:

如果您没有在 switch 中使用这些值,您可以这样做:

public class A
{
    public static final int FOO;
    public static final String BAR;

    static
    {
        FOO = 42;
        BAR = "Hello, World!";
    }
}

then the compiler will no longer hard code the values in the other classes that are using them.

那么编译器将不再对使用它们的其他类中的值进行硬编码。

回答by Julius Musseau

Suppose ClassA looks like this:

假设 ClassA 如下所示:

public class ClassA {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

If you recompile it, ClassB will continue using the old values. I guess it could depend on the compiler, but I think this is the typical behaviour. If you don't want to recompile ClassB everytime a constant in ClassA changes, you'll have to do something like this:

如果重新编译它,ClassB 将继续使用旧值。我想这可能取决于编译器,但我认为这是典型的行为。如果您不想每次 ClassA 中的常量更改时都重新编译 ClassB,则必须执行以下操作:

public class ClassA {
    public static final int FOO = CONST(1);
    public static final int BAR = CONST(2);

    public static int CONST(int i) { return i; }
}

Becuase now javac is unwilling to inline the constants. Instead it will call the CONST(int) method when ClassA's static initializer runs.

因为现在 javac 不愿意内联常量。相反,它会在 ClassA 的静态初始化程序运行时调用 CONST(int) 方法。