成员变量和局部变量初始化的问题

时间:2021-07-21 19:37:11
public class TestSwitch{
public static void main(String args[]){
TestSwitch tni = new TestSwitch();
String s = tni.convert(4);
System.out.println(s);
}

public String convert(int n){
String day;//这里为什么可以不用初始化?难道day是成员变量吗
switch(n){
case 1: 
day = "星期一";
break;
case 2: 
day = "星期二";
break;
case 3: 
day = "星期三";
break;
case 4: 
day = "星期四";
break;
case 5: 
day = "星期五";
break;
case 6: 
day = "星期六";
break;
case 0: 
day = "星期日";
break;
default:
day = "非法";
break;
}
return day;
}
}

20 个解决方案

#1


String day;//这里为什么可以不用初始化?难道day是成员变量吗 
   成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊

#2


引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
    成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊


可以初始化啊,你把它改为 String day="asdfgadgjjfsadk";一样。
为什么它不初始化?因为下面要根据输入的那个数字来赋值,这里先初始化是多此一举,并且下面所有情况都处理了,所以这里不用初始化。不初始化还有个好处,就是它省了内存空间。
String day="asdfgadgjjfsadk";如果它在内存中没找到asdfgadgjjfsadk的内存地址,会在内存中分配个内存段给它存储asdfgadgjjfsadk,而下面又赋值了,同样去找那些汉字,没有的话,又要分配内存。而已分配给asdfgadgjjfsadk的内存要等到JVM垃圾回收才释放掉。。。所以说在一段时间内省了内存。

个人理解,请大虾指教

#3


楼上的我知道可以初始化,我想问的是day在这里是局部变量,而java中引用局部变量时一定要先初始化了才能用...

#4


引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
  成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊
因为下面的case语句已经帮它赋值了.....根据传入的值不同,对应的case语句条不同,方法里是先声明变量后面再根据case语句中的内容帮它复制,所以它不是不用初始化而是已经在下面给了初始化了下面这种情况才是不给初始化不能通过编译,运行...
package algorithm;

public class TestSwitch {
public static void main(String args[]) {
String s = "s";
TestSwitch tni = new TestSwitch();
tni.convert(s);
}

public String convert(String s) {
String day;
s = day;
System.out.println(s);
return s;
}
}

#5



public class Test{
 public static void main(String args[]){
        int result;//
for(int i=1;i<=100;i++){
result+=i;
}System.out.println(result);
}
}如果这样编的话程序会报错,说result是局部变量要初始化后才行,而上面那个day同理也应是局部变量为何就那样呢纠结啊啊啊啊神啊

#6


引用 4 楼 davidcoffee 的回复:
引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
  成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊

因为下面的case语句已经帮它赋值了.....根据传入的值不同,对应的case语句条不同,方法里是先声明变量后面再根据case语句中的内容帮它复制,所以它不是不用初始化而是已经在下面给了初始化了下面这种情况才是不给初始化不能通过编译,运行...
package algorithm;

public class TestSwitch {
public static void main(String args[]) {
String s = "s";
TestSwitch tni = new TestSwitch();
tni.convert(s);
}

public String convert(String s) {
String day;
s = day;
System.out.println(s);
return s;
}
}

因为这里的result是明显没有初始化,而上面其实是已经初始化了不是不用初始化....

#7


public class TestForLoop {
public static void main(String args[]){
 int result;
for(int i=1;i<=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)

#8


你把switch中的default去掉试试,或者只是把default中的day的赋值去掉就明白了。
switch中存在default情况,编译器能分析出你使用day之前肯定初始化了。

而循环的情况下,编译器不会分析循环是不是真正执行,并不能保证在输出result之前已经初始化了。
比如你写个
for(int i=1;i <=100;i++){ 
还是
for(int i=1;i <=0;i++){
对编译器的分析行为是没有影响的 

#9


引用 7 楼 mqhong 的回复:
public class TestForLoop {
 public static void main(String args[]){
   int result;
  for(int i=1;i <=100;i++){
  result=2;
  }System.out.println(result);
 }
 }那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)


因为你的"初始化"在for内部做得

#10


那刚才那个初始化还不是在switch里的case里做的....为什么就不能在for里做呢

#11


引用 7 楼 mqhong 的回复:
public class TestForLoop {
public static void main(String args[]){
int result;
for(int i=1;i <=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)

局部变量的重要特点是只能被包含它的方法或方法里的程序块使用。另外,局部变量在被使用前一定要初始化,否则会带来错误,所以这里要么你把调用它的语句放在for循环里,因为result是在for循环里被初始化的,所以你放在for语句块外面还是等于初始化到....要么你就直接在for语句里直接声明然后初始化,再要么就是直接在最开始声明初始化,然后再调用,不管怎么样你不初始化就无法调用~像上面的case语句中,你把条件4随便改成什么字符串,到时候输出来的就是那个值,因为那个就是你初始化的值

#12


引用 8 楼 zangxt 的回复:
你把switch中的default去掉试试,或者只是把default中的day的赋值去掉就明白了。
switch中存在default情况,编译器能分析出你使用day之前肯定初始化了。

而循环的情况下,编译器不会分析循环是不是真正执行,并不能保证在输出result之前已经初始化了。
比如你写个
for(int i=1;i <=100;i++){
还是
for(int i=1;i <=0;i++){
对编译器的分析行为是没有影响的
OMG   八楼真够nb真如你所说的,如果把default去掉了eclipse立马说day是局部要初始化,看来default起作用了而不是case....

#13


引用 11 楼 davidcoffee 的回复:
引用 7 楼 mqhong 的回复:
public class TestForLoop {
public static void main(String args[]){
int result;
for(int i=1;i <=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)


局部变量的重要特点是只能被包含它的方法或方法里的程序块使用。另外,局部变量在被使用前一定要初始化,否则会带来错误,所以这里要么你把调用它的语句放在for循环里,因为result是在for循环里被初始化的,所以你放在for语句块外面还是等于初始化到....要么你就直接在for语句里直接声明然后初始化,再要么就是直接在最开始声明初始化,然后再调用,不管怎么样你不初始化就无法调用~像上面的case语句中,你把条件4随便改成什么字符串,到时候输出来的就是那个值,因为那个就是你初始化的值
你错了大哥,如果你去掉default就会发现,编译时会说没有初始化day,而你说的case已经初始化了这是明显不对的,我实践来了!刚刚操作来

#14


引用 10 楼 mqhong 的回复:
那刚才那个初始化还不是在switch里的case里做的....为什么就不能在for里做呢


因为switch跟for不同啊,switch的default会被编译器分析。for的第一个分号前面的会被for后面的分析。for内部的不算。
你可以用
String day;// 这里为什么可以不用初始化?难道day是成员变量吗
for (day = ""; day != "";) {
day = "a";
}
System.out.println(day); 
去试,保证又TMD不报错叻。。

乃乃的java真是害死人,楼主你说呢?

#15


好吧~my fault看来基础知识有待加强....你这么晚还在实践果然用功,囧

#16


引用 15 楼 davidcoffee 的回复:
好吧~my fault看来基础知识有待加强....你这么晚还在实践果然用功,囧


你还真喜欢这个 囧

#17


真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

#18


引用 17 楼 mqhong 的回复:
真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

学个三个月两个月的再来看这些小问题效果更好。
执着于这种东西上进步很慢,挫伤积极性。
感觉尽快的利用这种语言写程序才好,语言特性可以在写程序过程中分析、探究。

#19


引用 18 楼 zangxt 的回复:
引用 17 楼 mqhong 的回复:
 真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

 学个三个月两个月的再来看这些小问题效果更好。
 执着于这种东西上进步很慢,挫伤积极性。
 感觉尽快的利用这种语言写程序才好,语言特性可以在写程序过程中分析、探究。


同意,我当初一点java基础都没有,啃一本Java 2 Enterprise Edition啃叻两个星期还是啥不明白。但是就开始作项目叻。后来的慢慢也就知道叻。
一开始就追根问底确实会累的要死

#20


《Thingking in Java》里说是因为大部*部变量未赋初值属于编程者的失误而非有意,所以编译器要是自动赋值反而减少了错误被发现的可能。而类成员数据就不是这样子了。

#1


String day;//这里为什么可以不用初始化?难道day是成员变量吗 
   成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊

#2


引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
    成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊


可以初始化啊,你把它改为 String day="asdfgadgjjfsadk";一样。
为什么它不初始化?因为下面要根据输入的那个数字来赋值,这里先初始化是多此一举,并且下面所有情况都处理了,所以这里不用初始化。不初始化还有个好处,就是它省了内存空间。
String day="asdfgadgjjfsadk";如果它在内存中没找到asdfgadgjjfsadk的内存地址,会在内存中分配个内存段给它存储asdfgadgjjfsadk,而下面又赋值了,同样去找那些汉字,没有的话,又要分配内存。而已分配给asdfgadgjjfsadk的内存要等到JVM垃圾回收才释放掉。。。所以说在一段时间内省了内存。

个人理解,请大虾指教

#3


楼上的我知道可以初始化,我想问的是day在这里是局部变量,而java中引用局部变量时一定要先初始化了才能用...

#4


引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
  成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊
因为下面的case语句已经帮它赋值了.....根据传入的值不同,对应的case语句条不同,方法里是先声明变量后面再根据case语句中的内容帮它复制,所以它不是不用初始化而是已经在下面给了初始化了下面这种情况才是不给初始化不能通过编译,运行...
package algorithm;

public class TestSwitch {
public static void main(String args[]) {
String s = "s";
TestSwitch tni = new TestSwitch();
tni.convert(s);
}

public String convert(String s) {
String day;
s = day;
System.out.println(s);
return s;
}
}

#5



public class Test{
 public static void main(String args[]){
        int result;//
for(int i=1;i<=100;i++){
result+=i;
}System.out.println(result);
}
}如果这样编的话程序会报错,说result是局部变量要初始化后才行,而上面那个day同理也应是局部变量为何就那样呢纠结啊啊啊啊神啊

#6


引用 4 楼 davidcoffee 的回复:
引用 1 楼 mqhong 的回复:
String day;//这里为什么可以不用初始化?难道day是成员变量吗
  成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值....但是为什么我感觉这个day是局部变量啊,为什么也不用初始化的?我的天啊

因为下面的case语句已经帮它赋值了.....根据传入的值不同,对应的case语句条不同,方法里是先声明变量后面再根据case语句中的内容帮它复制,所以它不是不用初始化而是已经在下面给了初始化了下面这种情况才是不给初始化不能通过编译,运行...
package algorithm;

public class TestSwitch {
public static void main(String args[]) {
String s = "s";
TestSwitch tni = new TestSwitch();
tni.convert(s);
}

public String convert(String s) {
String day;
s = day;
System.out.println(s);
return s;
}
}

因为这里的result是明显没有初始化,而上面其实是已经初始化了不是不用初始化....

#7


public class TestForLoop {
public static void main(String args[]){
 int result;
for(int i=1;i<=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)

#8


你把switch中的default去掉试试,或者只是把default中的day的赋值去掉就明白了。
switch中存在default情况,编译器能分析出你使用day之前肯定初始化了。

而循环的情况下,编译器不会分析循环是不是真正执行,并不能保证在输出result之前已经初始化了。
比如你写个
for(int i=1;i <=100;i++){ 
还是
for(int i=1;i <=0;i++){
对编译器的分析行为是没有影响的 

#9


引用 7 楼 mqhong 的回复:
public class TestForLoop {
 public static void main(String args[]){
   int result;
  for(int i=1;i <=100;i++){
  result=2;
  }System.out.println(result);
 }
 }那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)


因为你的"初始化"在for内部做得

#10


那刚才那个初始化还不是在switch里的case里做的....为什么就不能在for里做呢

#11


引用 7 楼 mqhong 的回复:
public class TestForLoop {
public static void main(String args[]){
int result;
for(int i=1;i <=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)

局部变量的重要特点是只能被包含它的方法或方法里的程序块使用。另外,局部变量在被使用前一定要初始化,否则会带来错误,所以这里要么你把调用它的语句放在for循环里,因为result是在for循环里被初始化的,所以你放在for语句块外面还是等于初始化到....要么你就直接在for语句里直接声明然后初始化,再要么就是直接在最开始声明初始化,然后再调用,不管怎么样你不初始化就无法调用~像上面的case语句中,你把条件4随便改成什么字符串,到时候输出来的就是那个值,因为那个就是你初始化的值

#12


引用 8 楼 zangxt 的回复:
你把switch中的default去掉试试,或者只是把default中的day的赋值去掉就明白了。
switch中存在default情况,编译器能分析出你使用day之前肯定初始化了。

而循环的情况下,编译器不会分析循环是不是真正执行,并不能保证在输出result之前已经初始化了。
比如你写个
for(int i=1;i <=100;i++){
还是
for(int i=1;i <=0;i++){
对编译器的分析行为是没有影响的
OMG   八楼真够nb真如你所说的,如果把default去掉了eclipse立马说day是局部要初始化,看来default起作用了而不是case....

#13


引用 11 楼 davidcoffee 的回复:
引用 7 楼 mqhong 的回复:
public class TestForLoop {
public static void main(String args[]){
int result;
for(int i=1;i <=100;i++){
result=2;
}System.out.println(result);
}
}那分析下为什么这个编译也错呢,result=2不是算初始化了吗???那为什么编译时报错说system.out.println(result说这个是局部要初始化才得)


局部变量的重要特点是只能被包含它的方法或方法里的程序块使用。另外,局部变量在被使用前一定要初始化,否则会带来错误,所以这里要么你把调用它的语句放在for循环里,因为result是在for循环里被初始化的,所以你放在for语句块外面还是等于初始化到....要么你就直接在for语句里直接声明然后初始化,再要么就是直接在最开始声明初始化,然后再调用,不管怎么样你不初始化就无法调用~像上面的case语句中,你把条件4随便改成什么字符串,到时候输出来的就是那个值,因为那个就是你初始化的值
你错了大哥,如果你去掉default就会发现,编译时会说没有初始化day,而你说的case已经初始化了这是明显不对的,我实践来了!刚刚操作来

#14


引用 10 楼 mqhong 的回复:
那刚才那个初始化还不是在switch里的case里做的....为什么就不能在for里做呢


因为switch跟for不同啊,switch的default会被编译器分析。for的第一个分号前面的会被for后面的分析。for内部的不算。
你可以用
String day;// 这里为什么可以不用初始化?难道day是成员变量吗
for (day = ""; day != "";) {
day = "a";
}
System.out.println(day); 
去试,保证又TMD不报错叻。。

乃乃的java真是害死人,楼主你说呢?

#15


好吧~my fault看来基础知识有待加强....你这么晚还在实践果然用功,囧

#16


引用 15 楼 davidcoffee 的回复:
好吧~my fault看来基础知识有待加强....你这么晚还在实践果然用功,囧


你还真喜欢这个 囧

#17


真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

#18


引用 17 楼 mqhong 的回复:
真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

学个三个月两个月的再来看这些小问题效果更好。
执着于这种东西上进步很慢,挫伤积极性。
感觉尽快的利用这种语言写程序才好,语言特性可以在写程序过程中分析、探究。

#19


引用 18 楼 zangxt 的回复:
引用 17 楼 mqhong 的回复:
 真郁闷今晚,花了我两个小时搞懂了两个问题,这些问题别人都不会去在乎,可我老是想把什么都搞的一清二楚,往往这样很累,做人真累

 学个三个月两个月的再来看这些小问题效果更好。
 执着于这种东西上进步很慢,挫伤积极性。
 感觉尽快的利用这种语言写程序才好,语言特性可以在写程序过程中分析、探究。


同意,我当初一点java基础都没有,啃一本Java 2 Enterprise Edition啃叻两个星期还是啥不明白。但是就开始作项目叻。后来的慢慢也就知道叻。
一开始就追根问底确实会累的要死

#20


《Thingking in Java》里说是因为大部*部变量未赋初值属于编程者的失误而非有意,所以编译器要是自动赋值反而减少了错误被发现的可能。而类成员数据就不是这样子了。

#21