4

Using 'this();' inside an if statement in a constructor does not throw a compiler error.

It should throw 'Call to 'this()' must be the first statement in a constructor'; If it is allowed then it should work but does not in my case.

The code is allowed to run but is calling the base constructor twice which throws a run-time exception. I do not understand why.

Here is a Base class

public virtual class CompilerErrorBase {
      protected final Map<String,Integer> Counts;

      public CompilerErrorBase() {
          this.Counts = new Map<String,Integer>();
    }
}

This class works

public class CompilerWorks extends CompilerErrorBase {
    private final Date aDate;

    public CompilerWorks(Date a, Date b, Date c) {
        this(b);
    }
    public CompilerWorks(Date a, Date b) {
        this();
    }
    public CompilerWorks(Date a) {
        aDate = a;
    }
    public CompilerWorks() {
        aDate = Date.today();
    }
}

This class does not

public class CompilerErrorExample extends CompilerErrorBase {
    private final Date aDate;
    public CompilerErrorExample(Date a, Date b) {
        if (b == null){
            this();
        }
        else{
            this(b);
        }

    }
    public CompilerErrorExample(Date a) {
        aDate=a;

    }
    public CompilerErrorExample() {
        aDate = Date.today();
    }
}

In CompilerErrorExample class the base class constructor is called twice and throws

System.FinalException: Final variable has already been initialized

I do not understand why CompilerWorks class does not throw same error

  • 3
    Sounds like you found a bug. Have you opened a case with support? – Adrian Larson Aug 3 '17 at 21:21
  • Yes I knew it must be a bug. Since it is not unique to my org I saw no reason to create a support ticket and spend additional time on it. – Maggie Aug 4 '17 at 12:39
  • 2
    Well that's generally how they find out they have bugs in the system. – Adrian Larson Aug 4 '17 at 13:16
3

This is definitely a bug. A call to an alternative constructor or parent constructor must be the first method called in a constructor, as noted here:

When you use the this keyword in a constructor to do constructor chaining, it must be the first statement in the constructor.

It is not allowed, so a compiler bug at best.

  • could you use a ternary to try to get around this? – Caspar Harmer Aug 8 '17 at 18:37
  • @CasparHarmer Nope. A call to this or super must be the very first expression. If you need a common initializer, use an instance method. – sfdcfox Aug 8 '17 at 19:18
  • Yes, I think I remember trying to use a ternary a while back... as I recall, no joy. – Caspar Harmer Aug 8 '17 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.