Guice: injecting a parameter used in implementation of abstract method - java

Here is an example of the issue I've come across:
public interface IFoo { ... }
public abstract class Helper implements IFoo {
public Helper() { ... }
protected abstract X helperMethod();
}
public class Foo extends Helper {
private final String aaa;
#Inject
public Foo(String aaa) { this.aaa = aaa; }
#Override
X helperMethod() { doSomethingUsingWhatsInjected(aaa); }
}
The issue is that when I bind IFoo to Foo like this:
bind(IFoo.class).to(Foo.class).in(Singleton.class);
it appears like helperMethod() is being called before the aaa has been Injected since I'm seeing aaa as null. But if I instead don't use the class Helper and in-line all of its code directly in Foo, guice doesn't struggle.
What's the difference between these two approaches? Why is helperMethod() called before we know from where we're getting the implementation of IFoo? Can we use Helper along with injection?

Are you sure you're not calling helperMethod from within Helper's constructor? You omitted that part from the code you posted, but it would match the behavior you're seeing.
public class Test {
interface IFoo { }
static abstract class Helper implements IFoo {
Helper() { helperMethod(); }
abstract void helperMethod();
}
static class Foo extends Helper {
private final String aaa;
Foo(String aaa) { this.aaa = aaa; }
#Override
void helperMethod() { System.out.println(String.valueOf(aaa)); }
}
public static void main(String[] args) {
// Call helperMethod twice:
// once in the Helper.Helper(), once right here.
new Foo("expected").helperMethod();
// output:
// null
// expected
}
}
The first thing Foo does is implicitly call its superclass constructor, as if you typed super(); this necessarily happens as the very first statement in the subclass constructor. Consequently, this happens even before final variables like aaa are set, so your overridden method in Foo sees aaa as null. As in my example, this is not specific to Guice, but Guice injection can trigger the constructor just like anything else can.
This StackOverflow answer offers a more thorough discussion of this problem.

Related

How to nest methods in java to force user to use the nested name?

I'm writing a library, for more readability I want to force user to use nested methods to call the correct functions.
For example this is my class looks like:
public class Foo{
public void methodA(){}
public void methodB(){}
public void methodC(){}
}
What I'm expecting the user:
Foo foo = new Foo();
foo.methodA.methodB();
foo.methodA.methodC();
to call method B & C through calling the methodA as a prefix
After reading your question i think you are asking about Builder Design patten in which every methods return type is same class object and you can make call hierarchy like this.
obj.aMethod().bMethod().cMethod();
in your example just do like this:
public class Foo{
private static final Foo instance = new Foo();
private Foo(){}
public static Foo getInstance(){
return instance;
}
public Foo methodA(){
//Do stuff
return getInstance();
}
public Foo methodB(){}
public Foo methodC(){}
}
Now you can call like objfoo.getInstance().methodA().methodB();
Hope it will help you. To read more about that pattern
To force the user to use methodA to access methodB you could use an inner class.
In methodB you can access the Foo-Object with Foo.this.
public class Foo{
public Bar methodA()
{
// ...
return new Bar();
}
public class Bar {
private Bar() {}; // only methodA can create a Bar object
public void methodB(){}
public void methodC(){}
}
}
This is called as method chaining. You will need to set the return type of all methods as the same as the Class.
public class Foo{
public Foo methodA()
public Foo methodB()
public Foo methodC()
}
Now the client can simply call:
foo.methodA().methodB(), etc.
You can have one "terminal method" i.e. one that does not return a value. For example
public void methodD();
This method will be called last.
foo.methodA().methodB().methodC().method();
This line in itself will be valid as return type is void.
Please look at method chaining/ builder pattern YouTube videos, it will be clear.

interface - Overridden methods are not inherited

I was reading Java SCJP book by Khalid A. Mughal (for JE6), and in topic 7.6 Interfaces and Page number 313, it is given that
A subinterface can override abstract method declarations from its superinterfaces. Overridden methods are not inherited.
I could not quite understand what "Overridden methods are not inherited." means. I tried to do this:
interface A
{
void abc();
}
interface B extends A
{
#Override
void abc();
}
interface C extends B
{
void abc();
}
And I did not get any error. What am I not understanding?
This simply means that overridden methods can have a slightly different signature than the superinterface's methods. For example:
public interface Foo {
Object doSomething(String input) throws IOException;
}
public interface Bar extends Foo {
#Override
String doSomething(String input);
}
As you can see, in the subinterface, I no longer throw a checked exception, and I guarantee that the returned object is a more specific type. The method that did throw a checked exception is not inherited, because it is overridden.
I don't have the context of the entire paragraph, but there's something else related that applies only to implementations and not interfaces, which is that if you override a method without explicitly calling super, the superclass's implementation won't occur.
For example, if I have:
public class Example {
public static class Foo {
public void printSomething() {
System.out.println("Foo");
}
}
public static class Bar extends Foo {
#Override
public void printSomething() {
System.out.println("Bar");
}
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.printSomething();
}
}
This program will simply output:
Bar
but NOT Foo. If I add a call to super.printSomething(), then it will print both.

How do you deal when the implementation for an interface method is the same for some classes?

Assume I have defined interface ISomeInterface with methods foo and bar.
E.g.
public interface ISomeInterface {
public void foo();
public void bar();
}
Let's say I have classes A and B that for them it makes sense to both implement the interface. But it also does not make sense to have a different implementation for foo().
Taking into account that deriving A from B or B from A is incorrect/weird is there a standard coding practice for this design?
I assume I could create some utilities class to implement foo() and call it as a delegate but I was wondering if this whole structure can be dealt with differently
Update:
To give a full understanding of my question I stumbled upon this:http://perlbuzz.com/2010/07/why-roles-in-perl-are-awesome.html and I was trying to understand if this feature is lacking from the traditional OO concepts as we use them in Java or not
Your edit suggests that your true question is: "Is there an equivalent for Perl roles in Java?"
Since Java 8 introduced default methods in interfaces, interfaces with default methods seem like a very good equivalent for roles. Especially, you can do what you want in your example: Provide a default implementation for foo():
interface ISomeInterface {
public default void foo(){ /* your default impl goes here */}
public void bar(); // Abstract, must be implemented by subclasses
}
class A implements ISomeInterface {
// must only implement bar, can reuse foo's default impl
}
class B implements ISomeInterface {
// must only implement bar, can reuse foo's default impl
}
If there is a feature about roles I am missing please let me know. Otherwise, I think Java8 interfaces are a quite good surrogate for roles.
Decided to turn my comment into an answer:
You could use an abstract class rather than an interface:
public abstract class FooBar {
public void foo(){
//your implementation goes here
}
abstract void bar();
}
public class A extends FooBar{
#Override
public void bar(){
}
}
Why not something like this :
public class abstract SomeAbstractClass {
public void foo(){
//implementation
}
public abstract void bar();
}
class A extends SomeAbstractClass {
}
class B extends SomeAbstractClass {
}
public abstract class SomeClass implements ISomeInterface {
public void foo() {
// I do stuff..
}
}
public class A extends SomeClass {
public void bar() {
// A specific impl. of bar..
}
}
public class B extends SomeClass {
public void bar() {
// B specific impl. of bar..
}
}
Alternatively, if you don't want A and B to be tied up by extending an abstract class you can just use composition. This also provides the flexibility to change the IFoo behaviour at run time if you were to inject the FooImpl as part of the constructor. In this example I have just hard wired the FooImpl for brevity.
public class B implements ISomeInterface {
private IFoo foo = new FooImpl();
public void foo() {
foo.doSomethingFooey();
}
public void bar() {
// B specific implementation
}
}
public class A implements ISomeInterface {
private IFoo foo = new FooImpl();
public void foo() {
foo.doSomethingFooey();
}
public void bar() {
// A specific implementation
}
}

Warn developer to call `super.foo()` in java

Lets say I have these two classes, one extending the other
public class Bar{
public void foo(){
}
}
public class FooBar extends Bar {
#Override
public void foo(){
super.foo(); //<-- Line in question
}
}
What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?
Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?
for example:
public abstract class Bar{
public Bar(Class<? extends Bar> cls){
Object instance = getInstance();
if (!instance.getClass().equals(cls)) {
throw new EntityException("The instance given does not match the class given.");
}
//Find the method here if it has been overriden then throw an exception
//If the super method isn't being called in that method
}
public abstract Object getInstance();
public void foo(){
}
}
public class FooBar extends Bar {
public FooBar(){
super(FooBar.class);
}
#Override
public Object getInstance(){
return this;
}
#Override
public void foo(){
super.foo();
}
}
Maybe even an annotation I can put on the super method so it shows that it needs to be called?
EDIT
Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method
I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.
Edit 2
This here is what I wanted in a way:
But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead
EDIT: To answer the edited, question, which includes:
I would even be happy with making the method "un-overrideable"
... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
To answer the original question, consider using the template method pattern instead:
public abstract class Bar {
public foo() {
// Do unconditional things...
...
// Now subclass-specific things
fooImpl();
}
protected void fooImpl();
}
public class FooBar extends Bar {
#Override protected void fooImpl() {
// ...
}
}
That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.
what you could do is something like following
public class Bar{
public final void foo(){
//do mandatory stuff
customizeFoo();
}
public void customizeFoo(){
}
}
public class FooBar extends Bar {
#Override
public void customizeFoo(){
//do custom suff
}
}
foo method made 'final' in superclass so that subclasses can't override and avoid doing mandatory stuff

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Categories