循环体中申明变量

今天在看java代码时发现一句

1
2
3
4
while()
{
final A a=other.getA();
}

疑惑之处:final为不可更改,那么循环体循环回来时是更改还是新建呢?

C语言代码中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main(void)
{
int i;
for(i=0;i<10;i++)
{
int k;
printf("%d ",k);
k++;
}
}
int main(void)
{
int i;
for(i=0;i<10;i++)
{
int k;
printf("%d ",&k);
k++;
}
}

输出为连续的10个数,10个一样的地址
反汇编结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.text:00401520 _main proc near ; CODE XREF: ___tmainCRTStartup+269p
.text:00401520 push ebp
.text:00401521 mov ebp, esp
.text:00401523 and esp, 0FFFFFFF0h
.text:00401526 sub esp, 20h
.text:00401529 call ___main
.text:0040152E mov dword ptr [esp+1Ch], 0
.text:00401536 jmp short loc_401568
.text:00401538 ; ---------------------------------------------------------------------------
.text:00401538
.text:00401538 loc_401538: ; CODE XREF: _main+4Dj
.text:00401538 lea eax, [esp+18h]
.text:0040153C mov [esp+4], eax
.text:00401540 mov dword ptr [esp], offset aD ; "%d "
.text:00401547 call _printf
.text:0040154C mov dword ptr [esp], offset a123456 ; "123456"
.text:00401553 call _printf
.text:00401558 mov eax, [esp+18h]
.text:0040155C add eax, 1
.text:0040155F mov [esp+18h], eax
.text:00401563 add dword ptr [esp+1Ch], 1
.text:00401568
.text:00401568 loc_401568: ; CODE XREF: _main+16j
.text:00401568 cmp dword ptr [esp+1Ch], 9
.text:0040156D jle short loc_401538
.text:0040156F leave
.text:00401570 retn
.text:00401570 _main endp

变量在循环体外声明时的反编译结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
text:00401520 _main proc near ; CODE XREF: ___tmainCRTStartup+269p
.text:00401520 push ebp
.text:00401521 mov ebp, esp
.text:00401523 and esp, 0FFFFFFF0h
.text:00401526 sub esp, 20h
.text:00401529 call ___main
.text:0040152E mov dword ptr [esp+1Ch], 0
.text:00401536 jmp short loc_401568
.text:00401538 ; ---------------------------------------------------------------------------
.text:00401538
.text:00401538 loc_401538: ; CODE XREF: _main+4Dj
.text:00401538 lea eax, [esp+18h]
.text:0040153C mov [esp+4], eax
.text:00401540 mov dword ptr [esp], offset aD ; "%d "
.text:00401547 call _printf
.text:0040154C mov dword ptr [esp], offset a123456 ; "123456"
.text:00401553 call _printf
.text:00401558 mov eax, [esp+18h]
.text:0040155C add eax, 1
.text:0040155F mov [esp+18h], eax
.text:00401563 add dword ptr [esp+1Ch], 1
.text:00401568
.text:00401568 loc_401568: ; CODE XREF: _main+16j
.text:00401568 cmp dword ptr [esp+1Ch], 9
.text:0040156D jle short loc_401538
.text:0040156F leave
.text:00401570 retn
.text:00401570 _main endp

java代码中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main{
public static void main(String[] args)
{
int[] l=new int[]{1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < 10; i++) {
final int a=l[i];
System.out.println(a);
}
}
}

结果为运行无误1-10

结论

c语言中,在内在外除了初始化次数区别和作用域区别外其他都一样,不是重复声明
java中。。。。仔细想一下应该是不重新分配栈里的…..要不然太浪费栈了,java对栈的保护应该相当严密