5

I have a constructor which gets a HashSet and a HashMap. I need to run a validation check on one hashMAp and combine it with the hashSet, as 'super' must receive only one hashSet. I can't find a way to do it as I get following error: cannot reference this before supertype constructor

Example:

public class A extends B {
  public A(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
    super(new C (h1) ); //h1 should contain changes related to m1..
}

I want to do something like that:

public class A extends B {
      public A(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
        runMyFunc(h1,m1);
        super(new C (h1) );
    }



 runMyFunc(HashSet<Obj> h1, HashMap<UID,Objects> m1){
      //do checks
      //more checks...
      // if something then h1.setUid(m1.get(0))... 
      return h1;
   }

I thought converting the constructor to private and then run it like that:

public class A extends B {
  private A(HashSet<Obj> h1) {
    super(new C (h1) ); 
}

 public A(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
     runMyFunc(h1,m1);
     this(h1);
 }

but it also didn't work.

Can you please advice?

user1386966
  • 3,302
  • 13
  • 43
  • 72
  • Can't you simply set a `super`'s field at the end of `A`'s constructor calls? – Grzegorz Górkiewicz Jan 29 '17 at 13:20
  • 2
    A call to `super()` or `this()` must be the first line in a constructor. `super()` is called automatically (with no arguments) if you don't insert it yourself. You can get around the problem by using a factory method. – Axesilo Jan 29 '17 at 13:25

2 Answers2

6

Just make your runMyFunc static, and invoke it as a function where you use the return value in the super invocation. That is allowed:

public class A extends B {
  public A(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
     // Invoke as function rather than by itself on a separate line
     super(new C (runMyFunc(h1,m1)) );
  }

  // Make method static
  public static HashSet<Obj> runMyFunc(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
     //do checks
     //more checks...
     // if something then h1.setUid(m1.get(0))... 
     return h1;
  }
Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
5

Make your method static and make sure it returns your new h1.

public static HashSet<Obj> runMyFunc(HashSet<Obj> h1, HashMap<UID,Objects> m1) {
     // Some mutation to h1
     return h1;
}

Use it in the first line as follows:

this(runMyFunc(h1,m1));

But why?

You must be wondering "Why am I able to use static methods and not instance methods?". Well, before you can call your methods, your parent's object has to be instantiated first, this is meant to help the compiler prevent you from accessing attributes/methods/whatever that are not yet available. Static methods are safe cause by definition can't access any of that.

Related posts