-1

I came across a code, and 1 thing stumped me. Here is the code

static public Return fun1()
{
  return new register(new SomeMap[]{
         null, 
         new SomeMap(new Basic(String.class), new Basic(String.class))
  })
  { 
    @Override
    public Return getSomething(int val)
    {
     ....
    }
  };
}

As you can see the override callback method is defined outisde the scope of new register(..). The call back function seems to be defined outside within its own code block. Is this possible? How does this work?

) is before the function override.

Shouldn't it be like this?

static public Return fun1()
    {
      return new register(new SomeMap[]{
             null, 
             new SomeMap(new Basic(String.class), new Basic(String.class))
      }
      
        @Override
        public Return getSomething(int val)
        {
         ....
        }
      );
    }




public static class register extends SomeMap
{
   public register(SomeMap[] somemaps)
   {
   }

    public Return getSomething(int val)
    {
     ....
    }
}

public static abstract class SomeMap
{
   // no constructors here just some method definitions here
}
Yogi
  • 1,035
  • 2
  • 13
  • 39

1 Answers1

1

While a regular simple anonymous class looks just

new Anonymous() {
    public void method() {
        // implementation
    }
};

The example takes a SomeMap[] constructor argument, but otherwise it's the same thing

new register(       // New anonymous class
    new SomeMap[]{  // Provide SomeMap[] for the constructor
         null,      // SomeMap[0] contains null
         new SomeMap(new Basic(String.class), new Basic(String.class)) // SomeMap[1] has data
    }) {            // End constructor 
        // Define the method, in the right place
        @Override
        public Return getSomething(int val) {
        }
    };  // End anonymous class

I wouldn't let that kind of code fly though, even if it were properly formatted.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I am just confused about the part, wherein override function is outside `)`. shouldnt it follow the initializer block immediately after? – Yogi Jun 15 '21 at 19:07
  • There's no initializer block. The method definition has to be outside `)`, because otherwise it would be inside the constructor parameters. – Kayaman Jun 15 '21 at 19:09
  • oh. I got confused, because this is what is described here https://stackoverflow.com/questions/5310403/how-to-initialize-anonymous-inner-class-in-java Also, `getSomething()` has to be part of `SomeMap` only right? – Yogi Jun 15 '21 at 19:17
  • `SomeMap` (or rather `SomeMap[]`) is the constructor parameter, so not right. – Kayaman Jun 15 '21 at 19:19
  • Also, we cant invoke constructor inside anonymous class and thats why we use initializer block, right? – Yogi Jun 15 '21 at 19:19
  • Still not right, it's an [abstract class constructor](https://stackoverflow.com/a/10370992/2541560) that's being called. Not that common syntax, at least anymore, which is all more reason to rewrite that code. – Kayaman Jun 15 '21 at 19:24
  • So you mean we are invoking constructor for whatever object register expects and that object constructor expects SomeMap arguments and `getSomething` method is part of that abstract class? – Yogi Jun 15 '21 at 19:26
  • I thought its not possible to invoke constructor inside an anonymous class. – Yogi Jun 15 '21 at 19:33
  • Well, then you learned something [new](https://stackoverflow.com/a/14625945/2541560) today. It's pretty uncommon, IIRC back with Swing's `AbstractAction` it got some use, i.e. `new AbstractAction("Push") {` then you'd define `actionPerformed()`. – Kayaman Jun 15 '21 at 19:37
  • So `register` extends `SomeMap`. SomeMap is the abstract class. SomeMap doesnt have `getSomething` or the constructor. How is the constructor invoked? – Yogi Jun 15 '21 at 20:42
  • Show all the classes involved. In the comments under the question you claim that `register` extends `Return`. The code clearly indicates that there is a constructor `register(SomeMap[])` and a method `Return getSomething(int)` as it's enforced by the `@Override` annotation. – Kayaman Jun 15 '21 at 20:54
  • I updated. yes. The Return class extends SomeMap and has the constructor and `getSomething`, But we are calling constructor on SomeMap(which is abstract and has no constructor). My confusion is shouldnt we override method from SomeMap? But we are overriding method from `Return` and invoking constructor from `SomeMap` (which is not defined explicitly) – Yogi Jun 15 '21 at 21:04
  • Hey Sorry:( I updated the question with relevant classes – Yogi Jun 15 '21 at 21:23
  • I updated with classes and relevant codes – Yogi Jun 16 '21 at 16:14
  • Yes, it's creating a new anonymous subclass of `register`. Since there's no no-arg constructor, that could be called by an implicit `super()`, you need to provide constructor arguments. – Kayaman Jun 16 '21 at 16:45
  • So in a nutshell, we are creating a subclass of `register`. Since we want to pass our own values to register, we are passing the arguments to `constructor` of the register and NOT `SomeMap`. The constructor of `register` takes arguments of type `SomeMap`(which is an abstract class). Since `register` has a parametrized constructor, we need to invoke it every time. All this confusion could have been avoided if we had just used lambdas – Yogi Jun 16 '21 at 17:14
  • @kayman: Am I understanding correctly? Thank you so much for your patience and lucidity.. – Yogi Jun 16 '21 at 17:14
  • Subclass yes, we **have** to pass values to the constructor. `SomeMap` isn't relevant since constructors aren't inherited anyways. `SomeMap` can't be abstract since a new instance is created at `new SomeMap(new Basic(String.class), new Basic(String.class))`. On the other `register` would need to be abstract for this to make some sense design-wise. Concrete class here is either the result of poor design, misunderstanding or a hack put together. – Kayaman Jun 16 '21 at 18:01
  • Sorry, why do you say `register` should be abstract? Why is it a poor design to have a concrete class? And do you mean since we are instantiating `SomeMap`, it no longer is abstract even if its declared one? Even I have never seen a concrete class being used inside anonymous class. Thats what began the whole confusion – Yogi Jun 16 '21 at 18:13
  • Implementing an interface or extending an abstract class as an anonymous class had uses pre-lambda, but it's very questionable for a concrete class. `SomeMap` is not declared an abstract class based on the code you've shown. See line 4 of my second code block, where it's clearly instantiated. – Kayaman Jun 16 '21 at 18:22
  • I added the declaration for `SomeMap`. `SomeMap` is indeed declared as abstract class. But it is getting instantiated as you have shown in your example – Yogi Jun 16 '21 at 18:30
  • So either you're not looking at the right class or you have a magic abstract class that can be instantiated with a constructor that doesn't exist. – Kayaman Jun 16 '21 at 18:35
  • :) Let me check again – Yogi Jun 16 '21 at 18:37
  • It says here https://www.java67.com/2013/02/can-abstract-class-have-constructor-in-java.html#:~:text=Yes%2C%20an%20abstract%20class%20can,no%20argument%20in%20abstract%20class.&text=In%20order%20to%20use%20an,and%20provide%20a%20concrete%20class. "an abstract class can have a constructor in Java. You can either explicitly provide a constructor to abstract class or if you don't, the compiler will add default constructor of no argument in abstract class. This is true for all classes and it also applies to an abstract class." – Yogi Jun 16 '21 at 18:43
  • You still can't instantiate an abstract class, so there's a clear conflict between what you say and what the code says. But since you're not showing the real code, it's no use guessing and it doesn't really matter concerning the anonymous class. – Kayaman Jun 16 '21 at 19:18
  • l will check again. You have been very helpful. Thank you so much :) – Yogi Jun 16 '21 at 20:23