A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© houyudong 中级黑马   /  2014-4-27 20:11  /  1298 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 houyudong 于 2014-4-28 21:22 编辑

class B
{
        int i;
        int j = 10;
        boolean falg;
        public B()
        {
                System.out.println("以前的值是" + i +""+ j +"" +falg);
                int i = 88;
                int j = 99;
                boolean falg = true;
        }
        public void show()
        {
                System.out.println("i =" + i);
                System.out.println("j =" + j);
                System.out.println("falg =" + falg);
        }
}
public class test
{
        public static void main(String[] arge)
        {
                B bb = new B();
                bb.show();
        }
}
如上所示:我定义了一个类为B,定义了int i ,int j = 10, boolean falg,输出值正确,而我在构造函数中再次将int i ,int j , boolean falg,三个函数定义了一次,而且分别赋其他值,输出却是原来全局变量值,为什么没有报错?

11 个回复

正序浏览
成员变量和局部变量 的问题 你在局部变量的时候又int 一次,代表又建立了一个int类型的
回复 使用道具 举报
class B
{
        int i;//在这里定义的变量属于全局变量
        int j = 10;
        boolean falg;
        public B()
        {
                System.out.println("以前的值是" + i +""+ j +"" +falg);
                int i = 88;//在这里定义的变量是局部变量,而且在你程序中没有使用到这些局部变量
                int j = 99;//(因为局部变量不读),所以不会与全局变量产生冲突
                boolean falg = true;//如果没有语法上的错误是不会报错了
                //所以上的定义的只限于本类中使用
        }
        public void show()
        {
                System.out.println("i =" + i);
                System.out.println("j =" + j);
                System.out.println("falg =" + falg);
        }
}
public class Test
{
        public static void main(String[] arge)
        {       
                B bb = new B();
                bb.show();
        }
}

回复 使用道具 举报
本帖最后由 evar71 于 2014-4-27 23:16 编辑
  1. class B
  2. {
  3.         int i;
  4.         int j = 10;
  5.         boolean falg;
  6.         public B()
  7.         {
  8.                 int i = 88;
  9.                 int j = 99;
  10.                 boolean falg = true;
  11.                 System.out.println("以前的值是" + i +""+ j +"" +falg);
  12.                
  13.         }
  14.         public void show()
  15.         {
  16.                 System.out.println("i =" + i);
  17.                 System.out.println("j =" + j);
  18.                 System.out.println("falg =" + falg);
  19.         }
  20. }
  21. class Test
  22. {
  23.         public static void main(String[] arge)
  24.         {
  25.                 B bb = new B();
  26.                 bb.show();
  27.         }
  28. }
复制代码
我把你的代码改成上面的内容,也就是把构造函数里的定义i、j、falg的部分移动到了System打印之前,输出结果如下:

可见,构造函数是给对象初始化的,所以“以前的值”显示的是构造函数内定义的局部变量的值;调用方法时显示的是类变量的值,因为构造函数中的ij是重新定义的,和类变量的ij没有关系。
回复 使用道具 举报
你在构造器(构造函数)中给i,j,falg赋值的时候,没报错是因为你重新定义了他们,而你在构造函数中定义的i,j,falg并不是成员变量,而是局部变量!
如果你想重新给i,j,falg赋值,则要用this关键字,比如:this.i=88    this.j=99   this.falg=true。
回复 使用道具 举报
本帖最后由 136616244 于 2014-4-27 21:13 编辑
  1. package cn.nanjing.oop;
  2. import java.util.*;
  3. public class Demo01 {
  4. //Java中传的到底传是值还是引用?
  5. public void addInt(int i){
  6. //i+=1;//i=i+1与i+=1的区别是:后者会做类型的自动转换,如果i+1超出int型范围的话会将超出的部分切掉,结果有可能变成负数。
  7. //而前者如果溢出直接编译不通过
  8. }
  9. public void addStr(String str){
  10. str+="111";
  11. }
  12. public void addList(List<String> strList){
  13. strList.add("List111");
  14. }
  15. public static void main(String[] args) {
  16. Demo01 d = new Demo01();
  17. int i = 0;
  18. String str = "s";
  19. List<String> strList = new ArrayList<String>();
  20. d.addInt(i);//java中参数传递时实质上只存在传值,当传递的是基本数据类型的时候他传递的值是的一个副本!
  21. //int i = 10;int j = i;j+=5的值是15 但i的值没有改变!
  22. d.addStr(str);//而当传递的是引用类型的参数时候,实际上传递还是一个引用类型的副本!既然引用类型参数传递的是引用类型的副本,那么两个引用
  23. //地址指向的对象将是同一个,但因为String对象的值不可改变,所以会在堆内存中重新开辟String对象,并将新的地址赋值给局
  24. // 部变量str(局部变量str作用的范围只有整个函数和整个代码块),


  25. d.addList(strList);//
  26. System.out.println(i);
  27. System.out.println(str);
  28. System.out.println(strList);
  29. }
  30. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
//Java中传的到底传是值还是引用?
回复 使用道具 举报
本帖最后由 执笔梦 于 2014-4-27 21:08 编辑

int i;
        int j = 10;  //在这定义一个变量i=10.
        boolean falg;
        public B()
        {
                System.out.println("以前的值是" + i +""+ j +"" +falg);
               /*                            int i = 88;             //你在这相当于又重新定义一个局部变量i=88.也是就说你这个i和上面那个i是没有关系的,j原理一样。               
                int j = 99;                           */

                 i=88;          //这样就是为上面全局的变量赋值...
                 j=99;
                falg = true;
        }
        public void show()
        {
                System.out.println("i =" + i);
                System.out.println("j =" + j);
                System.out.println("falg =" + falg);
        }





评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
class B {
        int i;
        int j = 10;
        boolean falg;

        public B() {
                //以下输出语句中的i和j都是类的成员变量
                System.out.println("以前的值是" + i + "" + j + "" + falg);
               
                /*
                 * 以下定义语句中的i和j都是Test()函数的局部变量
                 * 这两个i和j和成员变量的i和j不发生冲突,所以编译和执行都是可以通过的。
                 */
                int i = 88;
                int j = 99;
                boolean falg = true;
        }

        public void show() {
                System.out.println("i =" + i);
                System.out.println("j =" + j);
                System.out.println("falg =" + falg);
        }
}

public class Test {
        public static void main(String[] arge) {
                //初始化Test类的对象bb,虽然调用了Test()构造函数,但成员变量中的i和j的并没有发生变化
                B bb = new B();
                //show()方法中打印的是成员变量中的i和j,所以输出结果仍为0,10,false
                bb.show();
        }
}
回复 使用道具 举报
   老师讲的笔记,能帮到你不?
构造函数:用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种。
特点:
 1:该函数的名称和所在类的名称相同。
 2:不需要定义返回值类型。
 3:该函数没有具体的返回值。
记住:所有对象创建时,都需要初始化才可以使用。

注意事项:一个类在定义时,如果没有定义过构造函数,那么该类中会自动生成一个空参数的构造函数,为了方便该类创建对象,完成初始化。如果在类中自定义了构造函数,那么默认的构造函数就没有了。

一个类中,可以有多个构造函数,因为它们的函数名称都相同,所以只能通过参数列表来区分。所以,一个类中如果出现多个构造函数。它们的存在是以重载体现的。

构造函数和一般函数有什么区别呢?
 1:两个函数定义格式不同。
 2:构造函数是在对象创建时,就被调用,用于初始化,而且初始化动作只执行一次。
    一般函数,是对象创建后,需要调用才执行,可以被调用多次。
   
什么时候使用构造函数呢?
分析事物时,发现具体事物一出现,就具备了一些特征,那就将这些特征定义到构造函数内。

构造代码块和构造函数有什么区别?
  构造代码块:是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。
  构造函数:是给与之对应的对象进行初始化。它具有针对性。

Person p = new Person();
创建一个对象都在内存中做了什么事情?
1:先将硬盘上指定位置的Person.class文件加载进内存。
2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
5:对空间中的属性进行显示初始化。
6:进行实体的构造代码块初始化。
7:调用该实体对应的构造函数,进行构造函数初始化。()
8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)
回复 使用道具 举报
本帖最后由 jack_93 于 2014-4-27 20:26 编辑

那个,构造函数你定义的是方法变量,前面是类变量,作用域不一样
回复 使用道具 举报
  1. public B() {
  2.                 System.out.println("以前的值是" + i + "" + j + "" + falg);
  3.                 int i = 88;//这是新创建的对象,是局部变量 ,构造方法结束就销毁,可将int 删去,就是修改的全局变量 下同
  4.                 int j = 99;
  5.                 boolean falg = true;
  6.         }
复制代码
回复 使用道具 举报 1 0
您需要登录后才可以回帖 登录 | 加入黑马