1

There are 4 classes in my UiAutomator test project:

1:

public class A {
protected E e;
public T t = null;
protected String m ,v;
protected long L;

public A(){
    t = new T();
}

public A(E e, String m, String v, String tf)
{
    this.e = e;
    this.m = m;
    this.v = v;
    t = t.loadXML(tf);
}

2:

public class B extends A {

public B(E e, String m, String v, String tf)
{
    this.e = e;
    this.m = m;
    this.v = v;
    t = t.loadXML(tf);
}

3:

public class C {
private B b = null;
private D d = null;
private E e = null;

public C(B b, E e, D d)
{
    this.b = b;
    this.e = e;
    this.d = d;
}

4:

public class D extends B{

public D (E e, String m, String v, String tf)
{
    super(e, m, v, tf);
    this.e = e;
    this.m = m;
    this.v = v;
    t = t.loadXML(tf);
}

I am getting a NullPointerException when the program tries to use methods of class D (class C have method that use A, B, D).
There are no problem in A, B, C.
Methods in D call methods from B and I think I have some issues with extending? Also how can I use methods of B in D without extending the class? Thanks!

Idos
  • 15,053
  • 14
  • 60
  • 75

2 Answers2

2

A few things: Despite t being a generic, you're assuming that T has a method loadXML(); yet, there are no restrictions on what T may be.

Additionally, here's where your NullPointerException is:

D constructor calls the constructor for B, but the constructor for B does not call the default constructor for A, which initializes T. Since t is not initialized, you get a NullPointerException.

Steve P.
  • 14,489
  • 8
  • 42
  • 72
0

See Default constructors and inheritance in Java for more information on default constructors and inheritance in Java.

I'm not sure what you're doing to get the NullPointerException, but I'll point out the errors I've noticed so far.

In A's constructor, you write:

t = t.loadXML(tf);

at that point t isn't initialized yet, so it's null and trying to call a method on it will cause a NullPointerException. This shouldn't be causing the NullPointerException in D in your code as it currently is (because B calls A's default constructor which will initialize t; see explanations below). There are 2 ways to solve this (depending on what you wanted to have happen): 1. Call A's other constructor (which initializes t):

public A(E e, String m, String v, String tf)
{
    this();
    this.e = e;
    this.m = m;
    this.v = v;
    t = t.loadXML(tf);
}
  1. Pass an argument t of type T to the constructor, and use that to help initialize t

    public A(E e, String m, String v, String tf, T passedT) { this(); this.e = e; this.m = m; this.v = v; t = passedT.loadXML(tf); }

Other notes. You could save yourself some work in B by calling A's constructor:

public B(E e, String m, String v, String tf)
{
    super(e,m,v,tf)
}

This would do all the same assignments that you currently do in B's constructor as it would call A's constructor and execute the code there. Currently, B's constructor will silently call A's default constructor (the one with no arguments). Explicitly, this would looks like:

public B(E e, String m, String v, String tf)
{
    super();
    this.e = e;
    this.m = m;
    this.v = v;
    t = t.loadXML(tf);
}

I'm assuming you added the super statement in D because it gave an error otherwise: B has no no-argument constructor defined, so D cannot call it and will give a compile error. That being said, D's constructor can be also simplified to:

public D (E e, String m, String v, String tf)
{
    super(e, m, v, tf);
}

I don't see you having specific issues with extending, except that you forgot to reuse the constructors of the parent classes.

To answer your last question, you can use methods of B in D by just calling them as if they're defined in D itself. Example:

public class B extends A {
    //I left out your constructors for readability
    public String getMAndV(){
       return m + v;
    }
}

public class D extends B {
    //I left out your constructors for readability
    public String getGivenStringAndMAndV(String givenString){
       return givenString + getMAndV(); //so just call it as if it's defined in the class itself
    }
}
Community
  • 1
  • 1
HSquirrel
  • 839
  • 4
  • 16