Java 在循环内创建最终变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/609609/
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
creating final variables inside a loop
提问by Jens Jansson
is this allowed in java:
这在java中是否允许:
for(int i=0;i<5;i++){
final int myFinalVariable = i;
}
The keyword of my question is final
. Is it allowed to do a final variable that changes with every run of the loop? I was wondering this because final says that you can't change the value of the variable (calling only myFinalVariable = i
), but i'm redefining the whole variable with final int
.
我的问题的关键词是final
。是否允许执行随循环的每次运行而变化的最终变量?我想知道这一点,因为 final 说你不能改变变量的值(只调用myFinalVariable = i
),但我用final int
.
Are they two completely different variables just with the same name - with the variable from the previous run of the loop already heading down the road to the garbage collector?
它们是两个完全不同的变量,只是具有相同的名称 - 来自上一次循环运行的变量已经沿着通往垃圾收集器的道路前进了吗?
采纳答案by Greg Hewgill
Yes, it is allowed. The final
keyword means that you can't change the value of the variable within its scope. For your loop example, you can think of the variable going out of scope at the bottom of the loop, then coming back into scope with a new value at the top of the loop. Assigning to the variable within the loop won't work.
是的,这是允许的。该final
关键字意味着你不能改变的变量的值的范围之内。对于您的循环示例,您可以考虑变量在循环底部超出范围,然后在循环顶部以新值返回范围。分配给循环内的变量将不起作用。
回答by tehvan
You are right, for each iteration in the loop, you are creating a new variable. The variables do share the same name, but that's fine because they are not in the same scope. Next example would notwork:
您是对的,对于循环中的每次迭代,您都在创建一个新变量。变量确实共享相同的名称,但这很好,因为它们不在同一范围内。下面的例子将不能工作:
final int myFinalVariable = 0;
for(int i=0;i<5;i++){
myFinalVariable = i;
}
回答by TofuBeer
A variable is just a location on the stack. Try and keep your variables with as small a scope as possible and try to make them final. However scope and final are just source code things... from a code generation/VM point of view they don't really matter at all.
变量只是堆栈上的一个位置。尝试将变量保持在尽可能小的范围内,并尝试使它们成为最终变量。然而范围和最终只是源代码的东西......从代码生成/VM的角度来看,它们根本不重要。
In your specific example, using "int" no garbage is created. However if it were objects being created then for both cases the amount of garbage and when the garbage would be eligible for cleanup would be identical.
在您的具体示例中,使用“int”不会创建垃圾。但是,如果它是正在创建的对象,那么对于这两种情况,垃圾量和垃圾何时有资格进行清理将是相同的。
Take the following code:
取以下代码:
public class X
{
public static void main(final String[] argv)
{
foo();
bar();
}
private static void foo()
{
for(int i=0;i<5;i++)
{
final int myFinalVariable = i;
}
}
private static void bar()
{
for(int i=0;i<5;i++)
{
int myFinalVariable = i;
}
}
}
The compiler produces identical bytecode for each method:
编译器为每个方法生成相同的字节码:
public class X extends java.lang.Object{
public X();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2; //Method foo:()V
3: invokestatic #3; //Method bar:()V
6: return
private static void foo();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
private static void bar();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
}
Adding another method that declares the variable outside the loop give you slightly different bytecode due to the order that the variables are declared). Note that this version the variable cannot be made final. This last version is not the best way (the final variable inside the loop is the best if you can do it):
添加另一种在循环外声明变量的方法,由于声明变量的顺序,字节码略有不同)。请注意,此版本的变量不能成为最终版本。最后一个版本不是最好的方法(如果可以的话,循环中的最终变量是最好的):
private static void car()
{
int myFinalVariable;
for(int i=0;i<5;i++)
{
myFinalVariable = i;
}
}
private static void car();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_5
4: if_icmpge 15
7: iload_1
8: istore_0
9: iinc 1, 1
12: goto 2
15: return
}
回答by Basil Bourque
As answered, Yes, you may indeed mark the variables in a loop as 'final'. Here is the effect of doing so (Java 7, Eclipse Indigo, Mac OS X Lion).
正如回答的那样,是的,您确实可以将循环中的变量标记为“最终”。这是这样做的效果(Java 7、Eclipse Indigo、Mac OS X Lion)。
for ( int i = 0; i < 5; i++ ) {
// With 'final' you cannot assign a new value.
final int myFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration.
myFinalVariable = 7; // Compiler error: The final local variable myFinalVariable cannot be assigned.
// Without 'final' you can assign a new value.
int myNotFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration.
myNotFinalVariable = 7; // Compiler is OK with re-assignment of variable's value.
}
回答by Setu Poddar
Variable declared inside the loop have the scope only till the single execution of the loop.
在循环内声明的变量只有在循环执行之前才有作用域。
Declaring the variable as final inside the loop makes the no difference for the variable in side the loop, but if we declare the variable outside the loop with final modifier then the value assigned to primitive type or Object assigned to the reference variable cannot be changed .
在循环内将变量声明为 final 对循环内的变量没有区别,但是如果我们在循环外使用 final 修饰符声明变量,则分配给原始类型的值或分配给引用变量的对象将无法更改。
In the below example there is no issue with the first two loops both the loops give same output, but the third loop gives a compile time Error.
在下面的示例中,前两个循环没有问题,两个循环都给出相同的输出,但第三个循环给出了编译时错误。
public class test {
公开课测试{
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final int j= i;
System.out.println(j);
}
for (int i = 0; i < 5; i++) {
int j= i;
System.out.println(j);
}
final int j;
for (int i = 0; i < 5; i++) {
j= i;
System.out.println(j);
}
}
}
}
Please do correct me if i am wrong.
如果我错了,请纠正我。