Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java'的影响;最终';类成员变量的声明_Java_Performance_Variables_Final - Fatal编程技术网

Java'的影响;最终';类成员变量的声明

Java'的影响;最终';类成员变量的声明,java,performance,variables,final,Java,Performance,Variables,Final,这更多的是一个理论问题,而不是解决问题,所以请听我说 在C/C++和PHP中,可以声明常量。通常有两种方法可以做到这一点(#DEFINE例如,或“const type”…),其最终效果是在编译过程中进行替换,以便所有命名常量都成为文本。这很有帮助,因为不必访问内存位置来查找数据,数据是硬编码的,但没有硬编码的缺点——如果需要重用,则调用该值,如果需要更改,则更改该值的所有实例 但是Java的最终声明有点难以理解;因为我可以用未设置的final变量创建一个类,并在构造时对它们进行初始化,这意味着就

这更多的是一个理论问题,而不是解决问题,所以请听我说

在C/C++和PHP中,可以声明常量。通常有两种方法可以做到这一点(
#DEFINE
例如,或“
const type
”…),其最终效果是在编译过程中进行替换,以便所有命名常量都成为文本。这很有帮助,因为不必访问内存位置来查找数据,数据是硬编码的,但没有硬编码的缺点——如果需要重用,则调用该值,如果需要更改,则更改该值的所有实例

但是Java的
最终声明有点难以理解;因为我可以用未设置的final变量创建一个类,并在构造时对它们进行初始化,这意味着就我所知,它们不是作为文本预编译的。除了保证它们在构建后不能在逻辑上进行更改外,
最终
声明是否有助于提高效率

只要你记下解释
final
真正作用的部分,以及除了在构建后停止值更改之外,它还有什么好处,那么对文章的引用是可以的


作为推论,除了简单地使用文字(无论如何,这是一个坏主意)之外,是否有可能在Java中以任何其他方式声明编译级常量

Java确实有常量表达式。请参阅java语言规范中的

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

Literals of primitive type and literals of type String (§3.10.5)
Casts to primitive types and casts to type String
The unary operators +, -, ~, and ! (but not ++ or --)
The multiplicative operators *, /, and %
The additive operators + and -
The shift operators <<, >>, and >>>
The relational operators <, <=, >, and >= (but not instanceof)
The equality operators == and !=
The bitwise and logical operators &, ^, and |
The conditional-and operator && and the conditional-or operator ||
The ternary conditional operator ? :
Parenthesized expressions whose contained expression is a constant expression.
Simple names that refer to constant variables (§4.12.4).
Qualified names of the form TypeName . Identifier that refer to constant variables (§4.12.4).
编译时常量表达式是一个表示原语类型的值或字符串的表达式,该值或字符串不会突然完成,并且仅使用以下内容组成:
基本类型的文字和字符串类型的文字(§3.10.5)
强制转换为基本类型和强制转换为类型字符串
一元运算符+、-、~、和!(但不是++或--)
乘法运算符*、/、和%
加法运算符+和-
移位运算符,和>>>
关系运算符=(但不是instanceof)
相等运算符==和=
位运算符和逻辑运算符&、^和|
条件and运算符&&和条件or运算符||
三元条件运算符?:
包含表达式为常量表达式的括号表达式。
引用常量变量的简单名称(§4.12.4)。
表单TypeName的限定名称。指常量变量的标识符(§4.12.4)。

但在Java中,与C/C++不同的是,您还有一个JIT编译器,因此可以进行额外的内联。因此,底线是,在看到真正的性能问题之前不要担心。

Java确实有常量,Java编译器将在编译时用它们的值替换这些常量。例如,
final
String
类型的成员变量实际上是常量,可以用这种方式替换。(这是允许的,因为类
String
是不可变的)。这样做的后果之一是,如果在源代码中更改字符串,但不重新编译使用该字符串的类,则这些类将看不到该字符串的新值

JLS在以下段落中对此进行了解释:


最终字段旨在创建不可变对象

静态final字段是一种常量

编译器优化,数据流分析,在某种程度上发生了。如果您对此感兴趣,请尝试使用javap查看jvm字节码

最终声明是否有助于提高效率

不是真的。这是因为JIT通常可以确定值在运行时没有更改,并且可以将其视为最终值。(如果该值不是易失性的,并且在另一个线程中更改,则这是一个问题)


在Java 8中,如果可以将局部变量设置为最终变量,则可以在闭包中使用它们,而不必将它们声明为最终变量。

请参见此处:对于模拟/游戏,我必须以有效的方式开始,否则我将在以后花更多时间进行优化。在60帧/秒时,效果可能是几何的,甚至是效率低下的指数级。@RiverC,使用java中的JIT编译器,如果不进行测量,你真的无法猜测。您的一些过早优化实际上会破坏JIT编译器并使结果变慢。不等待最终产品完成是可以的,但您需要知道哪些功能需要执行这么多次,并在测试中运行它们并实际测量性能。我发现测试中的性能测量有些无用,因为根据我的经验,某些方面最终会因环境而异,而性能测试台往往会降低实际性能。简言之,检查数量级才是好的——也就是说,在总量中,哪些部分占用的时间最多,而不是绝对指标,这些指标总是被一个未知的数量所扭曲。长话短说,我希望实际的通用常数尽可能保持恒定——因为我最终可能不得不进行优化,为什么现在不做呢?我能看到的唯一原因是,正如您所说,我的过早优化是否会妨碍编译器本身的优化。如果编译器能够将静态final转换为常量,那么这是无关紧要的,我宁愿使用它们;这取决于编译器。这是令人失望的。非常有趣和有用。谢谢。我想做一些事情,这样我就不必依赖于编译器优化,而只是对某些值立即做最优化的事情。“最终字段旨在生成不可变对象。”原则上没有任何论据,但我发现这句话可能会误导。仅仅因为字段是final,就说它的数据是不可变的,这是错误的。由
final
vari指示的参考类型