4
public class Program {

    public static void main(String[] args) {
        Listener listener = new Listener();
        listener.listen();
    }
}

public class Listener {

    ServerQuery query;
    int test = 1;

    public listen() {
        query = new ServerQuery();
        Channel ch = new Channel();
        ch.dupa();
    }
}

public class Channel extends Listener {

    public dupa() {
        System.out.print(test); // works fine 
        super.query.doSomething(); // null pointer
        query.doSomething(); //  null pointer
    }
}

我无法访问“通道”类中的变量“查询”。谁能解释我为什么?

4

5 回答 5

3

您误解了超类型和子类型的概念。

直接的问题是您需要在使用它之前实例化查询变量。

要么ch.listen()在你打电话之前打电话,要么在dupa里面打电话dupa

这里的主要问题是理解子类型 - 超类型关系。

您的 Channel 对象没有对 的实例的引用Listener ,它只是它的子类型。因此,如果您需要访问超类型的字段,例如访问类的字段 - 您必须在使用它之前对其进行实例化。

在 Listener 中创建 Channel 对象没有逻辑。Channel 是一个 Listener,因此您可以创建它。

我建议您在这里或其他任何地方阅读更多有关它的信息。

对于您的代码,您可以使用:

public class Program {

    public static void main(String[] args) {
        Channel ch = new Channel();
        ch.listen(); // will instantiate ch.query
        ch.dupa(); 
    }
}
public class Listener {

    ServerQuery query;
    int test = 1;

    public listen() {
        query = new ServerQuery();
    }
}

public class Channel extends Listener {

    public dupa() {
        System.out.print(test);
        super.query.doSomething();
        query.doSomething();
    }
}
于 2013-03-05T15:08:47.563 回答
1

编辑以获得更多解释:

超类中的变量必须定义为受保护的,以允许由子类实现。如果您不声明范围,则该字段将声明为包私有。

有关范围的更多信息可以在官方教程中找到。

对您的代码的另一条评论:您的query变量未在此处实例化,因此如果您不listen()先调用该方法,它将始终返回 NPE。

于 2013-03-05T15:07:31.140 回答
0

您正在使用两个 Listener 对象。一个在 Channel 类中(比如 Channel.super()),一个在你的 main 方法中。

我认为令人困惑的是您假设您的 Channel 对象将使用您在 main 方法中声明的相同侦听器类。

简而言之,答案是查询变量未初始化。

所以主要是你有一个设计问题。您可以通过几种方式修复它。一个简单的方法是将查询传递给您的 dupa 方法并使用该查询对象。

于 2013-03-05T15:28:22.160 回答
0

我通过制作类似的东西解决了它:

public class Channel extends Listener {
     ServerQuery queryInstance;
     Listener(ServerQuery listener){
         queryInstance = listener;
     }
     public dupa() {

        System.out.print(test); // works fine 
        super.query.doSomething(); // null pointer
        query.doSomething(); //  null pointer
    }
}
于 2013-03-05T15:17:23.900 回答
0

Channel ch = new Channel();不初始化query

您正在调用dupa()对象Channel而不调用listen()初始化query引用。

于 2013-03-05T15:17:43.783 回答