package cn.com.starit.io;
class Base{
public Base(){
test();
}
public void test(){
System.out.println("aaaaa");
}
}class Sub extends Base{
private String name;
public void test(){
System.out.println("aaaaa"+name.length());//这里为什么会出现空指针异常 啊?
}
}public class test1 {
public static void main(String[] args){
Sub s = new Sub();
}
}

解决方案 »

  1.   

    引用类型默认值为null,也就是你程序中的 String name;
      

  2.   

    name没有初始化,默认值为null
      

  3.   

    name都是没有初始化,肯定为NULL了
    改成这个就不会为空了
    private String name="";
      

  4.   

    子类重写了test方法,父类构造函数会调用子类的test方法,而test方法中的name又是private,无法访问。另外,上面说的name为null也是个原因。以上纯属个人理解
      

  5.   

    同意此种见解,你只要把子类的test类该为和父类不用名和name赋值就可以出结果了。
      

  6.   

    同意此种见解,你只要把子类的test类改为和父类不同名的方法和name赋值就可以出结果了。
      

  7.   


    我可没说 改成private String name="";就不会为空了,呵呵其实改成什么,也为NullPointerException的,因为调用子类的test方法时,子类还没有进行初始化,但所有成员变量已经会有一个初始值,这是加载器默认分配的。这里的name就是null
      

  8.   

    请问下父类构造函数怎么调用子类的test方法的?
      

  9.   


    怎么会是父类调用子类呢?应该是“重写”机制,而和访问权限没有关系,希望大家也手动试一下,具体见解在8楼说明了,thx
      

  10.   

    子类覆盖了父类中的test方法,所以,当父类执行test方法,其实是子类的test方法,此时子类中的name没有被加载。name为null,当然报空指针异常了。
      

  11.   

    1. 创建子类对象时,执行子类的构造函数前会先执行父类的构造函数,因此new Sub()时会先执行父类的构造Base(),并执行init()2. 由于JAVA的多态性,父类构造函数Base()调用init()函数实际是执行子类的init()方法,而这时子类还没初始化构造子类对象,name成员为null, 因此出现楼主说的问题。纯属个人观点
      

  12.   

    嗯,是的,根访问权限无关,test()方法调用的还是子类中的name属性,只是没有初始化,一直是null
      

  13.   

    13楼很对。跟访问权限无关。即使name="", 因为子类重写,所以调用子类的方法,但这时候子类还没开始构造,成员变量name还不存在。
      

  14.   

      private String name; 都还没赋值肯定错拉 
      

  15.   

    test方法执行的是子类的test方法(覆盖),所以name 没有初始化也没赋值,为null,可以加上静态修饰,并赋值,这样就不会了,private static String name="";
      

  16.   

    这个和name是否为null根本没关系,也和权限没关系,主要是还没来得执行子类呢,既然还没来得及执行,那么久不确定是否存在成员变量,既然不确定是否有成员变量,那么name就没办法解析,当然为空。
      

  17.   

    就算子类里的string类型变量赋值了 是public修饰的 也是返回null
    已经测过了
    因为new Sub()的时候调用了父类的构造方法 然后又调用了test方法 在调用test的之前会检查方法有没有重写 然后因为是子类对象所以会调用Sub里的test方法 这个时候Sub.name还没有赋值 所以会有空指针错误
    个人见解...
      

  18.   

    类的加载顺序:父类静态块、子类静态块、父类成员、父类构造函数、子类成员、子类构造函数。如果父类构造函数中调用了已被子类重写的方法,则会进入子类重写的方法体内执行,如果该方法体中有引用子类的成员变量,由于子类成员还未初始化,所以会取其数据类型的默认值,此处name取null,所以会抛出空指针异常。修改方法是,使子类初始化的方法签名与父类不同,或者直接写入子类的构造函数中。
      

  19.   

     +1
    还是这位大哥聪明。
    我没看大家的问题前我试了一下。
    其实就是这样,LZ
    你这个问题和初始化的顺序也有一定的关系:
    1、 JVM首先将class的字节码 load进内存,然后初始化 static value ->static block,到父类 的实力变量,到父类的构造方法,到子类的实力变量,到子类的构造方法。
    值得注意的是,对象的创建(creation of new class instances)的时候,
    所有的成员变量—包括该类,及它的父类中的成员变量--被分配内存空间,并赋予默认值。(Btw,这里是第一次初始化成员变量)
    (b) 
    为所调用的构造函数初始化其参数变量。(如果有参数)
    (c) 如果在构造函数中用this 
    调用了同类中的其他构造函数,则按照步骤(b)~(f)去处理被调用到的构造函数。
    (d) 
    如果在构造函数中用super调用了其父类的构造函数,则按照步骤(b)~(f)去处理被调用到的父类构造函数。
    (e) 按照书写顺序,执行instance 
    initializer 和 instance variable initializer来初始化成员变量。(Btw,这里是第二次初始化成员变量)
    (f) 
    按照书写
    所以你这里的 name属性为 null,null调用 任何方法,都是不允许的。
    这里和private无关其实,你在Sub类内部自己通过length()方法访问 name属性,完全可以。
      

  20.   

    Base里面定义一个name并且赋值。
    而且要定义为Public就行了