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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黎健东 中级黑马   /  2012-8-29 04:15  /  3518 人查看  /  10 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黎健东 于 2012-8-29 04:18 编辑
  1. package com.lee.calc.test010;

  2. import java.util.ArrayList;
  3. import java.util.Iterator;

  4. public class Bug4Visit {
  5.    
  6.     public static void main(String[] args) {
  7.         
  8.         //该方法输出的报异常
  9.         BB b = new BB();
  10.         b.setA(true);
  11.         b.setB(true);
  12.         b.start();
  13.         BB c = new BB();
  14.         c.setA(true);
  15.         c.start();
  16.         
  17.         //正确输出的方法
  18.         AA a = new AA();
  19.         a.setA(true);
  20.         a.start();

  21.     }

  22. }

  23. class BB{
  24.     private ArrayList<String> alist;
  25.     private ArrayList<String> blist;
  26.     private boolean isA = false;
  27.     public boolean isA() {
  28.         return isA;
  29.     }

  30.     public void setA(boolean isA) {
  31.         this.isA = isA;
  32.     }

  33.     public boolean isB() {
  34.         return isB;
  35.     }

  36.     public void setB(boolean isB) {
  37.         this.isB = isB;
  38.     }

  39.     private boolean isB = false;
  40.     public BB() {
  41.         
  42.     }
  43.    
  44.     void start(){
  45.         if(isA){
  46.             newAddPrint(alist);
  47.         }
  48.         if(isB){
  49.             newAddPrint(blist);
  50.         }
  51.     }
  52.    
  53.     void newAddPrint(ArrayList<String> list){
  54.         newList(list);            
  55.         addList(list);            
  56.         printList(list);
  57.     }
  58.      
  59.     void newList(ArrayList<String> list){
  60.         list = new ArrayList<String>();
  61.     }
  62.    
  63.     void addList(ArrayList<String> list){
  64.         list.add("1");
  65.         list.add("2");
  66.         list.add("3");
  67.     }
  68.    
  69.     void printList(ArrayList<String> list){
  70.         Iterator<String> it = list.iterator();
  71.         String s;
  72.         while(it.hasNext()){
  73.             s = it.next();
  74.             System.out.println(s);
  75.         }
  76.     }
  77. }

  78. class AA{
  79.     private ArrayList<String> alist = new ArrayList<String>();
  80.     private ArrayList<String> blist = new ArrayList<String>();
  81.     private boolean isA = false;
  82.     public boolean isA() {
  83.         return isA;
  84.     }

  85.     public void setA(boolean isA) {
  86.         this.isA = isA;
  87.     }

  88.     public boolean isB() {
  89.         return isB;
  90.     }

  91.     public void setB(boolean isB) {
  92.         this.isB = isB;
  93.     }

  94.     private boolean isB = false;
  95.     public AA() {
  96.         
  97.     }
  98.    
  99.     void start(){
  100.         if(isA){
  101.             addList(alist);
  102.             printList(alist);
  103.         }
  104.         if(isB){        
  105.             addList(blist);            
  106.             printList(blist);
  107.         }
  108.     }
  109.      
  110.    
  111.     void addList(ArrayList<String> list){
  112.         list.add("1");
  113.         list.add("2");
  114.         list.add("3");
  115.     }
  116.    
  117.     void printList(ArrayList<String> list){
  118.         Iterator<String> it = list.iterator();
  119.         String s;
  120.         while(it.hasNext()){
  121.             s = it.next();
  122.             System.out.println(s);
  123.         }
  124.     }
  125. }
复制代码
请教一下,这个问题也困扰我一段时间了。
看BB这个类,直面上应该可以看出我的用意是,用户需要用到blist的时候,在new blist,但是我那样子写是报错的

如果照AA这个类写,没有报错,可是实例化这个类就连带吧blist也给new了,如果这个类里边还有clist dlist elist flist.....
而用户在使用这个类,只是用到其中的一个alsit或者其他一个list的时候,难道只能像AA这样写,实例化AA这个类的时候,就非得把这么多list实例化不管有没用到?

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

10 个回复

倒序浏览
准备上课去了,混脸熟。。。
回复 使用道具 举报
自己顶一下
回复 使用道具 举报
本帖最后由 黑马张涛 于 2012-8-29 16:41 编辑
  1. import java.util.ArrayList;
  2. import java.util.Iterator;
  3. public class BugTest {
  4.      
  5. public static void main(String[] args) {
  6.         
  7.    //该方法输出的报异常
  8.   
  9.          BB b = new BB(true,true);
  10.   
  11.          b.start();
  12.   
  13.          BB c = new BB(true,false);
  14.   
  15.          c.start();
  16.          
  17.          //正确输出的方法
  18.   
  19.          AA a = new AA();
  20.   
  21.          a.setA(true);
  22.   
  23.          a.start();
  24.          
  25.      }
  26. }
  27. class BB{
  28.   
  29.      private ArrayList<String> alist;
  30.   
  31.      private ArrayList<String> blist;
  32.   
  33.      private boolean isA = false;
  34.      private boolean isB = false;
  35.      
  36.      BB(boolean isA,boolean isB)
  37.      {
  38.       this.isA=isA;
  39.       this.isB=isB;
  40.      }
  41.      void start()
  42.      {
  43.       if(isA)
  44.       {
  45.        alist=new ArrayList<String>();
  46.        newAddPrint(alist);
  47.       }
  48.       if(isB)
  49.       {
  50.        blist=new ArrayList<String>();
  51.        newAddPrint(blist);
  52.       }
  53.       System.out.println(alist instanceof ArrayList);
  54.       System.out.println(blist instanceof ArrayList);
  55.          }
  56.   
  57.      
  58.      void newAddPrint(ArrayList<String> list){  
  59.   
  60.          addList(list);           // 用你的方法调用创建对象的方式,我在addList之前加 instanceof 判断语句显示alist或blist都还不是ArrayList实例,我觉得可能是Jvm执行顺序决定的
  61.   
  62.          printList(list);
  63.   
  64.      }
  65.      void addList(ArrayList<String> list){
  66.   
  67.          list.add("1");
  68.   
  69.          list.add("2");
  70.   
  71.          list.add("3");
  72.   
  73.      }
  74.   
  75.      
  76.      void printList(ArrayList<String> list){
  77.   
  78.          Iterator<String> it = list.iterator();
  79.   
  80.          String s;
  81.   
  82.          while(it.hasNext()){
  83.   
  84.              s = it.next();
  85.   
  86.              System.out.println(s);
  87.   
  88.          }
  89.   
  90.      }
  91.   
  92. }

复制代码

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 黄珊珊 于 2012-8-29 16:59 编辑

package com.lee.calc.test010;

import java.util.ArrayList;

import java.util.Iterator;

public class Bug4Visit {

   
    public static void main(String[] args) {

        

        //该方法输出的报异常

        BB b = new BB();

        b.setA(true);

        b.setB(true);

        b.start();

        BB c = new BB();

        c.setA(true);

        c.start();

        

        //正确输出的方法

        AA a = new AA();

        a.setA(true);

        a.start();

    }

}

class BB{

    private ArrayList<String> alist;

    private ArrayList<String> blist;
//这里的alist、blist只是一个引用变量,没有指向任何对象,所以方法里面的list只是一个副本,new出来的对象也跟原来的没关系。

所以这里要先给对象进行实例化。
其实在Java中,所有的方法调用,无论参数是基本数据类型还是对象,都是值传递。


    private boolean isA = false;

    public boolean isA() {

        return isA;

    }

    public void setA(boolean isA) {

        this.isA = isA;

    }

    public boolean isB() {

        return isB;

    }

    public void setB(boolean isB) {

        this.isB = isB;

    }

    private boolean isB = false;

    public BB() {

        

    }

   
    void start(){

        if(isA){

            newAddPrint(alist);

        }

        if(isB){

            newAddPrint(blist);

        }

    }

   
    void newAddPrint(ArrayList<String> list){

        newList(list);            

        addList(list);            

        printList(list);

    }

     

    void newList(ArrayList<String> list){

        list = new ArrayList<String>();

    }

   
    void addList(ArrayList<String> list){

        list.add("1");

        list.add("2");

        list.add("3");

    }

   
    void printList(ArrayList<String> list){

        Iterator<String> it = list.iterator();

        String s;

        while(it.hasNext()){

            s = it.next();

            System.out.println(s);

        }

    }

}

class AA{

    private ArrayList<String> alist = new ArrayList<String>();

    private ArrayList<String> blist = new ArrayList<String>();

    private boolean isA = false;

    public boolean isA() {

        return isA;

    }

    public void setA(boolean isA) {

        this.isA = isA;

    }

    public boolean isB() {

        return isB;

    }

    public void setB(boolean isB) {

        this.isB = isB;

    }

    private boolean isB = false;

    public AA() {

        

    }

   
    void start(){

        if(isA){

            addList(alist);

            printList(alist);

        }

        if(isB){        

            addList(blist);            

            printList(blist);

        }

    }

     

   
    void addList(ArrayList<String> list){

        list.add("1");

        list.add("2");

        list.add("3");

    }

   
    void printList(ArrayList<String> list){

        Iterator<String> it = list.iterator();

        String s;

        while(it.hasNext()){

            s = it.next();

            System.out.println(s);

        }

    }

}






评分

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

查看全部评分

回复 使用道具 举报
黑马张涛 发表于 2012-8-29 16:39

所以,在new对象的时候,都必须显式的将  ... 变量 = new ...这样写出来,而不能像我BB类写的根据传一个值
.... 传值 = new ...这样的写法?
回复 使用道具 举报
黄珊珊 发表于 2012-8-29 16:49
package com.lee.calc.test010;

import java.util.ArrayList;

那有什么修改的方法吗
回复 使用道具 举报
private ArrayList<String> alist;
private ArrayList<String> blist;
将class BB中的这两句代码该为:
private ArrayList<String> alist = new ArrayList<String>();
private ArrayList<String> blist = new ArrayList<String>();
这样当主函数在调用相应的对象时,就不会出现null了。

其实你这种想要在调用时再建对象的思路是不错。但在这里不太适用,你这样不先进行实例初始化,除了java中方法的值传递特性外,有时候还有可能会出现绕过某些程序,直接去访问null对象的情况。所以建议你还是先实例化对象。

回复 使用道具 举报
唐见 中级黑马 2012-8-29 18:14:55
9#
黑马张涛 发表于 2012-8-29 16:39

觉得这个可行。
回复 使用道具 举报
本帖最后由 寇龙飞 于 2012-8-29 19:01 编辑

看代码中我注释标记的部分,是你的b.start()开始执行后,函数调用运行顺序。其中你的参数传递有问题,所以到  list.add("1");这句话报空指针异常!
  1. class BB {
  2.         private ArrayList<String> alist;//隐式默认初始化为null
复制代码
  1.         void start() {
  2.                 if (isA) {
  3.                         newAddPrint(alist);//alist = this.alist;
  4.                 }
  5.                 if (isB) {
  6.                         newAddPrint(blist);
  7.                 }
  8.         }

  9.         void newAddPrint(ArrayList<String> list) {//list = alist(值为this.alist)
  10.                 newList(list);
  11.                 addList(list);//list = alist(值为this.alist)
  12.                 printList(list);
  13.         }

  14.         void newList(ArrayList<String> list) {//传这个参数你就没用,那传他干嘛呀?
  15.                 list = new ArrayList<String>();//这句话没用,因为list没用到
  16.         }

  17.         void addList(ArrayList<String> list) {//list = alist(值为this.alist)
  18.                 list.add("1");//此时list是this.alist(值为对象创建时隐式默认初始化null)。故此报空指针异常。
  19.                 list.add("2");
  20.                 list.add("3");
  21.         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
黄珊珊 发表于 2012-8-29 17:34
private ArrayList alist;
private ArrayList blist;
将class BB中的这两句代码该为:

这样说我懂了,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马