0

While trying to understand the Dependency Injection principle I came across this example which I couldn't understand

   abstract class ExternalInvestmentBase {
    private static ExternalInvestmentBase sImpl;

    protected ExternalInvestmentBase() {
        sImpl = this;
    }

    public static String supply(String request) throws Exception {
        return sImpl.supplyImpl(request);
    }

    abstract String supplyImpl(String request)
            throws Exception;
}


class InvestmentUtil extends ExternalInvestmentBase {

    public static void init() {
        new InvestmentUtil();
    }


    @Override
    public String supplyImpl(String request) throws Exception {
        return "This is possible";
    }
}

public class IExternalInvestment {
    public static void main(String[] args) throws Exception {
        InvestmentUtil.init();

        String rv = ExternalInvestmentBase.supply("tt");
        System.out.println(rv);
    }
}

The main question is

  1. How does the "this" keyword in the base class work ?
  2. How did the ExternalInvestmentBase.supply("tt"); access the object ?
RangerReturn
  • 171
  • 3
  • 3
  • 18
  • If I'm not mistaken, this piece of code looks pretty pathological and doesn't contribute anything to the understanding of DI. It also doesn't compile due to non trivial causes. I think, one can skip it without a second thought. – Curiosa Globunznik Nov 22 '19 at 07:39
  • It is so wrong, it has no explanation and doesn't work at all. Issues like *Non static method ExternalInvestmentBase.supply can't be called from a static context.* – Curiosa Globunznik Nov 22 '19 at 07:51

1 Answers1

1

The keyword 'this' refers to your current object. The class ExternalInvestmentBase is getting assigned to sImpl as an Object. Here are the Oracle Doc's explaining what it means: https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html I'm not exactly sure why the code uses it that way, to me it seems weird.

Because you have sImpl holding ExternalInvestmentBase as an object the method newExternalInvestmentBase should call the supplymethod on sImpl. This is how ExternalInvestmentBase.supply("tt"); should accesses the object. The method ExternalInvestmentBase.supply can not be used because it is a non static method called from a static context. It wil result in a compilation error.

This article explains correct dependency injection: https://www.javatpoint.com/dependency-injection-in-spring

Quadrivics
  • 181
  • 2
  • 10
  • That is not what he asks. He asks for an explanation of using the 'this' keyword and how ExternalInvestmentBase.supply() accesses the object. That's what i explained. He did not ask about it compiling so i guess he's still writing the code and asked for pointers here to be able to finish it and make it compile. – Quadrivics Nov 22 '19 at 07:45
  • I agree that the code does not compile and is weirdly constructed, but he refers to it as an example he found. He asked two questions that are answered about that specific piece of code. A simple Google search on 'java dependency injection' gives him tons of results with correct examples. What are you suggesting i change to my answer? – Quadrivics Nov 22 '19 at 07:57
  • @curiosa - I've fixed the stupid error in the code snippet, what are your thoughts now - the sample compiles. – RangerReturn Nov 23 '19 at 10:29
  • @Quadrivics can you take a look once more and - this is DI as per the link you sent as well. The method supply method is accessible to the world but it needs some other class to inject its implementation (which in this case happens to be its child) and access it – RangerReturn Nov 23 '19 at 10:32
  • I have to confess, I was not familiar with the philosophical fringes of DI. @Quadrivics answer still applies. I found it instructive to step through the object creation and access with a debugger. That's what I saw: init() creates a single instance, which in the process creates sets the static variable sImpl to itself in its own constructor. Then there's a static call to supply, which redirects to sImpl. – Curiosa Globunznik Nov 23 '19 at 13:28
  • Maybe it is less mysterious, if you consider, that there's an implicit immediate [super()](https://stackoverflow.com/questions/10508107/why-call-super-in-a-constructor) call in the constructor. After that `this` has a defined value and can be assigned to `sImpl`. If you make the super call explicit and try to put it after the assignment, the compiler would balk. – Curiosa Globunznik Nov 23 '19 at 13:33
  • @Saurabh would you mind adding a link to the source where you found this example? – Curiosa Globunznik Nov 23 '19 at 13:38
  • @curiosa `there's an implicit immediate super() call in the constructor. After that this has a defined value` could you elaborate more on where you think `this` actually was made ? – RangerReturn Nov 24 '19 at 13:42
  • Somewhere on the way of the super call the *object* gets created. But `this` isn't a variable actually, it is a [keyword](https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html) which gives you a reference to the object. You won't find some java source anywhere doing ` this = something;` since it is a language feature. – Curiosa Globunznik Nov 24 '19 at 15:46