0

Why is it that the function bind() exist only when set inside scope curly braces?

public void initialize() {

    inputsAreFull = new BooleanBinding() {
        {
            bind();
        }

        @Override
        protected boolean computeValue() {
            return false;
        }
    };
}

IntelliJ automatically recommends bind() when inside curly braces, but the function doesn't exist outside of them?

This won't work:

public void initialize() {

    inputsAreFull = new BooleanBinding() {

        bind();

        @Override
        protected boolean computeValue() {
            return false;
        }
    };
}
slothiful
  • 5,548
  • 3
  • 12
  • 36

2 Answers2

7

The syntax you're using is a shortcut for declaring an implementation of type BooleanBinding. You're effectively inside a class declaration.

public void initialize(){

    inputsAreFull = new BooleanBinding() {
        // This is equivalent to a class level scope for your anonymous class implementation.
        {
            bind();
        }

        @Override
        protected boolean computeValue() {
            return false;
        }
    };
}

You can't randomly invoke methods at a class level without an initializer block. You can test this out by writing...

class MyClass extends BooleanBinding {
    bind(); // It's not gonna be very happy with you.

    @Override
    protected boolean computeValue() {
        return false;
    }
}

IDEOne with running example: http://ideone.com/EERkXB

See also What is an initialization block?

fabian
  • 80,457
  • 12
  • 86
  • 114
christopher
  • 26,815
  • 5
  • 55
  • 89
  • 2
    Thats not a static initializer block, its an instance initializer block – flakes Jul 01 '19 at 14:42
  • The syntax rules are much the same, despite my poor wording. Amending now! – christopher Jul 01 '19 at 14:44
  • Maybe intereseting for OP: https://stackoverflow.com/questions/3987428/what-is-an-initialization-block – sfiss Jul 01 '19 at 14:45
  • 2
    I think this answer could be enhanced with a definition/explanation of how the initializer block works compared to a ctor, and why we must use one in this case. – flakes Jul 01 '19 at 14:48
  • The main point I think you should add, is that you can't use a ctor because the class is anonymous; in order to create a ctor, you need to use the class name as the method name which is not discoverable at this time. The initializer block provides a workaround to this issue. – flakes Jul 01 '19 at 14:52
5

new BooleanBinding() { ... } introduces an anonymous child class of BooleanBinding.

Now bind is a protected method, hence it is not allowed to do inputsAreFull.bind().

But bind may be called in the anonymous initializer block { ... }in the child class body.

There is still a remark needed: as the object is not fully initialized at that moment; the code actually being executed in the BooleanBinding constructor (compilier takes care of that), the method bind should not be overridable. For that one may use a private or (here) a protected final method.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138