0 0

求!哪位大大帮忙看看为什么是空指针异常?5

两个接口InterfaceA, InterfaceB:

public interface InterfaceA {
      
void methodA();
}




public interface InterfaceB {
     
void methodB();
}

两个类A,B分别实现此两个接口:

public class A implements InterfaceA {
     
public void methodA() {
System.out.println("A implements InterfaceA");}
}



public class B implements InterfaceB {
     
public void methodB() {System.out.println("B implements InterfaceB");}
}

父类Super中,两个接口作为实例变量

public class Super {

public InterfaceA a;
public InterfaceB b;

public void useMethodA()  {

try{
a.methodA();
} catch (Exception ex){
System.out.println(ex.getMessage());
}

}

public void useMethodB(){
try{
b.methodB();
} catch (Exception ex){
System.out.println(ex.getMessage());
}
}
}



子类Son继承父类,(问题来乐!这时候public InterfaceA a = new A();可以成立的?new一个A的对象 然后直接可以赋给类型为InterfaceA的对象?)

public class Son extends Super {
      public InterfaceA a = new A();
      public InterfaceB b = new B();
}

写一个TestDrive, 编译成功,并正常调用了实现了接口的方法!

public class TestDrive {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
       Son s = new Son();
       s.useMethodA();
       s.useMethodB();
}

}

控制台输出:

null
null


问题补充:
meng22623 写道
public class Son extends Super {
      public InterfaceA a = new A();
      public InterfaceB b = new B();
}
这里你声明的a和b与父类的a和b根本没有关系。子类的a和b是自己特有的,你根本没有引父类的a和b。
就像feige1008这位兄台说的,
public class Son extends Super {
      a = new A();
      b = new B();
}
改成这样就可以了。


明白了!这里重新声明了一次~ 这样子类的useMethod方法就无法找到相关的实例变量,而成为空指针。

问题补充:
AngelAndAngel 写道
呵呵,我明白lz的意思了,我copy了一下你的代码,看了一下,我一开始也迷惑了。因为我开始觉得不应该是null,而是打印出那几个语句。我最初是这么想的:
Son既然是继承Super,并且也有两个
      InterfaceA a
     InterfaceB b
那么应该来说是继承并重写了父类的属性,也就是说a,b都应该是初始化了的,所以在调用的时候应该不会为null。

其实不是这样的,Son继承了Super,所以继承了Super的属性和方法,而这个时候呢,方法并没有重写,还是沿用了父类Super的,那么父类方法里面所有的元素都保持父类自己的特色,根本不会下放到子类,而父类的a,b都没有实例化,所以出现了null。


原因找到了,子类我重新声明了一次变量,因此方法useMethodA和useMethodB用到的a和b并没有初始化,因此用useMethod的时候,无法读取a和b的变量。

如果我不声明a,b 
直接用 a = new A(); b = new B();

就可以了,而不用重写那两个方法,因为方法已经从父类继承下来了,只要有相关的变量就可以了。

问题补充:
AngelAndAngel 写道
lz,其实你明白的 只是一个浅显的表象。按道理说,子类的属性跟父类的肯定有关系的(怎么会没关系呢),只是说在这里你子类方法没有重写,所以看不出有关系,而这个误区才刚刚解释了你的现象而已。
你仔细看一下我的回答。


我明白你的意思,但我的目的是想方法在父类就已经写好了,子类不用再重写。

因此我是希望将父类声明的a,b在子类实例化,然后在父类进行运算。但问题就出在,我子类的两个实例变量重新声明了,因此useMethod里用到的变量a,b并没有进行初始化。^^
OO 
2011年8月30日 01:34

6个答案 按时间排序 按投票排序

0 0

采纳的答案

public class Son extends Super {
      public InterfaceA a = new A();
      public InterfaceB b = new B();
}
这里你声明的a和b与父类的a和b根本没有关系。子类的a和b是自己特有的,你根本没有引父类的a和b。
就像feige1008这位兄台说的,
public class Son extends Super {
      a = new A();
      b = new B();
}
改成这样就可以了。

2011年8月30日 10:25
0 0

lz,其实你明白的 只是一个浅显的表象。按道理说,子类的属性跟父类的肯定有关系的(怎么会没关系呢),只是说在这里你子类方法没有重写,所以看不出有关系,而这个误区才刚刚解释了你的现象而已。
你仔细看一下我的回答。

2011年8月30日 12:50
0 0

public class Son extends Super {
      public InterfaceA a = new A();
      public InterfaceB b = new B();
}

此类变成
public class Son extends Super {
      a = new A();
      b = new B();
}
就好了。

2011年8月30日 09:34
0 0

呵呵,我明白lz的意思了,我copy了一下你的代码,看了一下,我一开始也迷惑了。因为我开始觉得不应该是null,而是打印出那几个语句。我最初是这么想的:
Son既然是继承Super,并且也有两个
      InterfaceA a
     InterfaceB b
那么应该来说是继承并重写了父类的属性,也就是说a,b都应该是初始化了的,所以在调用的时候应该不会为null。

其实不是这样的,Son继承了Super,所以继承了Super的属性和方法,而这个时候呢,方法并没有重写,还是沿用了父类Super的,那么父类方法里面所有的元素都保持父类自己的特色,根本不会下放到子类,而父类的a,b都没有实例化,所以出现了null。

2011年8月30日 09:20
0 0

InterfaceA a   InterfaceB b 你申明了两次,初始化了子类的,父类中的却是没有初始化的。

2011年8月30日 09:19
0 0

引用
问题来乐!这时候public InterfaceA a = new A();可以成立的?new一个A的对象 然后直接可以赋给类型为InterfaceA的对象?


只要A实现了实现了InterfaceA 接口就可以这么赋值,自动上转型,就好比
Object str = new String();或List list = new ArrayList()一个样

引用
控制台输出:

null
null


不会输出null的吧

public class Son extends Super {
      public InterfaceA a = new A();
      public InterfaceB b = new B();
}

Super类声明了两个字段a和b,并初始化为默认值null,子类Son又声明了两个字段a和b
Super类中useMethodA和useMethodB使用的还是Super类声明的a和b,因为没有初始化,会NullPointerException

如果要在子类初始化父类声明的对象,这样就可以了:
public class Son extends Super {
      a = new A();
      b = new B();
}

2011年8月30日 07:44

相关推荐

    空指针和0、NULL之间的关系

    接下来,让我们看看什么是空指针(null pointer)。如果将一个空指针常量转换为指针类型,那么这个指针就被称为空指针。例如,如果 p 是一个指针变量,那么 p = 0; p = 0L; p = '/0'; p = 3 - 3; p = 0 * 17; 等赋值...

    struts2+spring+hibernate整合中spring注入出错。页面中报空指针异常。高手来看看怎么决绝。

    如果在页面中出现空指针异常,通常意味着某个预期被注入的对象为null。 可能的错误原因及解决方案: 1. **配置错误**:检查Spring的配置文件(如`applicationContext.xml`),确保所有需要被注入的对象(如Service...

    sqoop.zip解决报空指针的问题所需要的jar

    4. **测试运行**:尝试运行引起空指针异常的Sqoop命令,看是否成功解决了问题。如果仍有问题,可能需要检查日志并进行更深入的故障排查。 5. **监控日志**:分析Sqoop的日志文件,查找具体的错误信息,这有助于定位...

    C++关于空指针的整理,全部都是自己亲身实践后所整理

    C++语言中空指针的使用是一项重要的技术,在新标准中建议使用nullptr代替NULL来声明空指针,但为什么C++11要引入nullptr?它与NULL相比又有什么不同呢?这篇文章将详细解释空指针的使用和nullptr的引入原因。 首先...

    Android中利用NetworkInfo判断网络状态时出现空指针(NullPointerException)问题的解决方法

    总的来说,当在Android应用中判断网络状态时,为了避免空指针异常,我们需要确保正确地处理可能为null的对象,特别是在涉及IPC操作时。同时,理解Android的系统服务和数据同步机制对于写出更健壮的代码至关重要。...

    你必须知道的495个C语言问题

    为什么这些问题如此频繁地出现? 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 5.17 说真的,真有...

    《你必须知道的495个C语言问题》

    为什么这些问题如此频繁地出现? 60 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 60 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 60 5.17 说真的...

    指针的经验(看了你还会害怕指针吗?)

    函数指针是一个特殊的指针,它可以存储函数的地址。函数指针可以作为参数传递给其他函数,也可以作为其他函数的返回值。例如: ```cpp int add(int x, int y) { return x + y; } int (*func_ptr)(int, int); // ...

    C_C++指针.pdf关于指针的使用,比较晕指针的可以看看

    - 指针所指向的类型描述了通过指针访问的数据应该被视为什么类型的数据。 - 指针的值是它所指向的内存地址。 - 指针本身也有一个固定的大小,用于存储地址信息。 掌握这些概念后,你就能更加熟练地理解和使用指针,...

    Android开发实现AlertDialog中View的控件设置监听功能分析

    之前给弹出的AlertDialog中的控件设置监听时,老是报空指针异常,之所以报空指针异常,是因为我findViewById写的有问题,因为我们需要给弹出框中的控件设置监听,直接用findViewById是找不到弹出框中的控件的,需要...

    c#异常含异常格式,抛出异常和自定义异常

    在C#编程中,异常处理是一项至关重要的技能,它能够帮助开发者优雅地处理程序运行时可能出现的错误,保证程序的健壮性和稳定性。本篇将深入探讨“异常格式”,“抛出异常”以及“自定义异常”这三大知识点。 首先,...

    C语言函数指针.doc

    看看上面三个表达式分别是什么意思? C):这很容易,fun3 是函数名,p1,p2 是参数,其类型为char *型,函数的返回值为char *类型。 B):也很简单,与C)表达式相比,唯一不同的就是函数的返回值类型为char**,是个...

    C语言FAQ 常见问题列表

    为什么这些问题如此经常地出现? o 6.12 我很困惑。我就是不能理解这些空指针一类的东西。 o 6.13 考虑到有关空指针的所有这些困惑, 难道把要求它们内部表达都必须为 0 不是更简单吗? o 6.14 说真的, 真有机器用...

    关于指针的理解---从空间看

    在C语言中,指针是程序设计中的一个重要概念,它提供了对内存地址的直接操作,使得我们可以高效地访问和修改内存中的数据。本篇将从空间的角度深入理解指针。 首先,我们需要了解指针的基本概念。指针是一个变量,...

    C++指针初学者必看

    指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。 让...

    C指针的相关书籍很全面的

    另外,多级指针是指指向指针的指针,如`int **pp`,它可以用来指向一个指针变量,间接访问目标变量。 6. **函数参数与指针**:在C语言中,函数参数传递通常是按值传递,但通过指针作为参数,可以在函数内部修改实参...

    Visual Studio 遇到了异常,这可能是由某个扩展导致的

    只要在VS2010源码编辑器中输入一个字符,它就报道错误了 "visual studio 2010 遇到了异常,可能是由某个扩展导致的......"。刚开始一看,以为是扩展引起的,那我就把vs中所有的扩展暂时禁用一下,结果bug还是依旧。...

    谁也别挡我看QQ空间加密相册

    让我们先看看没有加密的相册里面都有些什么照片! 再看看网址中有这样一个结尾:albumid=57e8c8a5-1738-43e0-96e4-71e28890cb4d albumid=665942244 albumid英文意思是相册的意思,后面的:665942244 我猜就是该相册...

Global site tag (gtag.js) - Google Analytics