Is it possible to instantiate an interface in java? - java

I was going through a java tutorial on Spring Retry and there I read about RetryCallback, which is an interface.
In the same tutorial, I found this chunk of code:
retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
#Override
public Void doWithRetry(RetryContext arg0) {
myService.templateRetryService();
...
}
});
The way I see it, an anonymous object of RetryCallback is being instantiated. But then we just read it's an interface.
Could someone explain what's happening here?
Although not required, but just in case here's a link to the tutorial

This:
new RetryCallback<Void, RuntimeException>() {
#Override
public Void doWithRetry(RetryContext arg0) {
myService.templateRetryService();
...
}
}
is an anonymous class. When this code is run, an object of class MyContainingClass$1, which implements RetryCallback, instantiated.
When instantiated within an instance method, anonymous classes have an implicit reference to the MyContainingClass instance, which is accessed via the syntax MyContainingClass.this.
Note that the 1 in the class name is actually n where the anonymous class is positioned nth relative to all anonymous classes in the containing class.

its just providing a inline implementation for that interface, its not instantiating the interface. its equivalent of creating a new class a that implements RetryCallback, and passing to to execute

The question written in the title of your post:
Is it possible to instantiate an interface in java?
No, it is not possible. From 4.12.6. Types, Classes, and Interfaces in JLS (bold emphasis added by me):
Even though a variable or expression may have a compile-time type that is an interface type, there are no instances of interfaces. A variable or expression whose type is an interface type can reference any object whose class implements (ยง8.1.5) that interface.

Related

Java strange syntax - (Anonymous sub-class)

I have come across below strange syntax, I have never seen such snippet, it is not necessity but curious to understand it
new Object() {
void hi(String in) {
System.out.println(in);
}
}.hi("strange");
Above code gives output as strange
thanks
You've created an anonymous sub-class of Object, which introduces a method, called hi, after which you invoke this method with parameter "strange".
Let's suppose you had:
class NamedClass extends Object {
void hi(String in) { System.out.println(in); }
}
NamedClass instance = new NamedClass();
instance.hi("strange");
If this class was needed at exactly one place, there's no real need of being named and so on - by making it an anonymous class, you get rid of its name, the class gets defined and instantiated and the hi method invoked immediately within a single expression.
You've created an annonymous sub-class of Object and then invoke the method.
Four types of anonymous inner class exists :-
1)Inner class,
2)Static nested classes
3)Method local inner classes
4)Anonymous inner classes
In Annonymous inner classes,you can define,instantiate and use that inner object then and there
This is perfectly normal and is Called an anonymous class it is used very often where if u want to pass an object reference to a function you will do it with anonymous classes or for the use of callbacks, now .hi at the end is valid because you just used the new operator to instantiate an object of type Object and you have a reference to it so that's why it works.

method resolution when instantiating an interface

EDIT: FORGOT THE CODE SNIPPET _ ADDED HERE
I am trying to learn Java from the book 'Learning Java' that has the following code snippet listed as an example for interface callbacks. In this code snippet, there is only 1 class implementing the interface TextReceiver. My question is - since this code is instantiating the interface directly, if there was another class that implemented the interface TextReceiver and provided a whole different method body to the interface method receivetext than the one in TickerTape, then how would java resolve the reference to the method receivetext in the sendText method of TextSource? This seems like it would introduce ambiguity - also, it seems credence to what I have seen online about not being able to instantiate interfaces - but wanted to confirm before assuming
interface TextReceiver {
void receiveText( String text );
}
class TickerTape implements TextReceiver {
public void receiveText( String text ) {
System.out.println("TICKER:\n" + text + "\n");
}
}
class TextSource {
TextReceiver receiver;
TextSource( TextReceiver r ) {
receiver = r;
}
public void sendText( String s ) {
receiver.receiveText( s );
}
}
I tried just writing this up myself to figure this out, but got stuck with issues compiling since all of these classes were in the same class. I know this sounds n00bish - but I figured you guys might have quick guidance to offer.
Thanks in advance!!!
Methods are dispatched at runtime by looking at the actual type of the object instance.
So if you have
TextReceiver one = new SomeTextReceiver();
TextReceiver two = new SomeCompletelyDifferentTextReceiver();
and then call
one.receiveText();
the JVM will look at the actual object and see what class it is of.
The call will be dispatched to the implementation provided by that runtime class.
At compile-time all that is known here is the interface, so the compiler will check that such a method exists in the interface, but at run-time the actual class can be determined and dispatched to.
Note that this process is different for static methods. Those do not have an associated instance and the compiler does decide which implementation to call. As a result, you cannot really override static methods to get runtime dispatch.
Java interfaces cannot be instantiated, the programmer has to specify what implementation of the interface he wants to instantiate.
For example, if you try to do this (replace INTERFACE with the name of the interface):
INTERFACE i = new INTERFACE();
you will get an error, because an interface cannot be instantiated.
What you must do is (replace IMPLEMENTATION with the name of the implementation of the interface):
INTERFACE i = new IMPLEMENTATION();
As you can see, you ALWAYS tell the program what implementation to use for an interface. There's no room for ambiguity.
In your example, the class TextSource is NOT instantating the interface TextReceiver (instantiation occurs with the "new" keyword). Instead, it has a constructor that receives the implementation of the interface as a parameter. Therefore, when you call TextSource you MUST tell it what implementation of TextReceiver to use.

Creating object with reference to Interface

A reference variable can be declared as a class type or an interface type.If the variable is declared as an interface type, it can reference any object of any class that implements the interface.
Based on the above statement I have made a code on understanding. As said above declared as an interface type, it can reference any object of any class that implements the interface.
But in my code is displaying displayName() method undefined at objParent.displayName():
public class OverridenClass {
public static void main(String[] args) {
Printable objParent = new Parent();
objParent.sysout();
objParent.displayName();
}
}
interface Printable {
void sysout();
}
class Parent implements Printable {
public void displayName() {
System.out.println("This is Parent Name");
}
public void sysout() {
System.out.println("I am Printable Interfacein Parent Class");
}
}
I am sure I have understood the wrong way. Can someone explain the same?
But in my code is displaying displayName()method undefined.
Right, because displayName is not defined in the Printable interface. You can only access the methods defined on the interface through a variable declared as having that interface, even if the concrete class has additional methods. That's why you can call sysout, but not displayName.
The reason for this is more apparent if you consider an example like this:
class Bar {
public static void foo(Printable p) {
p.sysout();
p.displayName();
}
}
class Test {
public static final void main(String[] args) {
Bar.foo(new Parent());
}
}
The code in foo must not rely on anything other than what is featured in the Printable interface, as we have no idea at compile-time what the concrete class may be.
The point of interfaces is to define the characteristics that are available to the code using only an interface reference, without regard to the concrete class being used.
The displayName() method is displayed as undefined because objParent declared as type Printable and the interface does not have such method. To be able to use method displayName(), you can declare it in interface Printable:
interface Printable {
void sysout();
void displayName();
}
Or cast objParent to type Parent first before calling method displayName():
Printable objParent = new Parent();
objParent = (Parent) objParent;
objParent.displayName();
You need to type cast it to get the access to the Parent methods
((Parent)objParent).displayName();
Compiler doesn't care about run-time. as far as the compiler is concerned, it checks if the reference type has a method called display in your interface type.
methods declared in your sub-class or implementing class are not part
of your super class/interface. thus you cannot invoke those methods
which are declared in sub-class with super class/interface reference
type.
Interfaces are basically another way of - breaking the rules of single inheritance.
By using interfaces, a child class can, both inherit it's parents methods and be forced to implement it's interface methods. Resulting in an easy to extend and maintain inheritance tree etc.
The catch however is, when the child is referenced under the parent, you only have access to the parent methods. To access the interface methods, you will need to cast or create the child under the interface reference type.
Interfaces also allow the collection of multiple classes of different families to be collected under the interface type. To what benefit I am yet to discover.
In my opinion, it is pointless since I still cannot achieve fully blown polymorphism anyways - by just using the parent reference type and still have access to the interface implementations.
wherever the method signature reside reference of that interface will not give any error. In your example your method sysout() is in interface so reference of the interface will not give any error, but for method displayName() interface reference gives an error. For that you have to use your class reference.

What is this kind of instantiation called in Java?

This may be a very elementary question for Java, but I just can't recall it and have no clue how to search it online.
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Thread.sleep(100);
}
}
I'm used to initializing an object using constructors like new OnClickListener(arg1, arg2, ...). In my own experience I've never override a method when constructing an object. I've only done it when extending a class. What is this kind of instantiation called in Java if there's any term for it? In what other cases should we use it?
That's an anonymous class. It's an implementation of the OnClickListener interface, but that implementation is unnamed. It's concise to write and the implementation is visible in the calling context (often useful for readability), but since it's an implementation in-place, you can't use it elsewhere.
Note also that it's an inner class and hence has a reference to its surrounding class.
See here for more info.
Re. the reference to a surrounding class. An inner class has an implicit reference to its outer class (you can see this if you attempt to serialise the inner class using, say, XStream. It'll pull the outer class along with it). If you have a variable in the outer class, you can reference it in the inner (provided it's a final variable, mind)
They are called anonymous classes.
Technically they are subclasses of the class being instantiated, and provide overridden method implementations.
They are useful when you want to provide an implementation without having to specifically declare a top level class.
They are Java's answer to closures.
new OnClickListener()
{
#Override
public void onClick(View v)
{
Thread.sleep(100);
}
}
Both from the syntax and semantics perspective, this construct is a blend of instantiation and class declaration. In the same breath you specify which constructor of OnClickListener to call (interfaces are assumed to have the default constructor for this purpose) and provide the class body that belongs to the new subclass you are declaring. You are not giving a name to the subclass, that's why this construct is called an "anonymous class". With an anonymous class instantiation is tightly coupled to declaration and you can't instantiate this class from any other point in code except where it is declared.
There is a nearly identical construct in Java that you'll almost never see used in practice: a local class. It looks just like a regular class declaration, but it occurs inside a method, just like the anonymous class above. In this case the class is given a name and can be referred to and instantiated on several places, but all of them inside the method where it is declared.
In both cases you get the special feature not available to any other class, which is the ability to use the local variables declared in the method. This is odd at first because the local variable disappears when the method completes, but the reference to an instance of the local class goes on living. This is why these classes are called "closures": they are said to "close over" their local environment. They kind of "lift" the variable declarations and keep them as their instance variables.
Just to give a bit of an example of how this could be used...
public class TestClass {
public static void main(String args[]) {
OutOfTheMain ootm = new OutOfTheMain();
}
}
public interface SuperInner {
String words = "hello";
String getWords();
}
public class OutOfTheMain {
OutOfTheMain() {
testInnerStuff(new SuperInner() {
#Override
public String getWords() {
return words + " world";
}
});
}
private void testInnerStuff(SuperInner sinner) {
System.out.println(sinner.getWords());
}
}
When ran, this would print...
hello world
You can override methods to add additional functionality and use this class later on at runtime.

how to access instance that 'owns' a method in java?

in java, is it possible to access the instance to which a method belongs, given only the method?
for example:
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
instanceB.receiveMethod(foo);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Object o = foo.getInstanceOwner(); // just made that part up...
}
}
my feeling is that methods belong to classes, not instances of a class, so the answer is no, but maybe there's some sneaky reflection technique i don't know about. i could always pass 'this' along with method foo, but that seems like extra baggage.
Taken from
A Method provides information about, and access to, a single method on a class or interface. The reflected method may be a class method or an instance method (including an abstract method).
A Method permits widening conversions to occur when matching the actual parameters to invoke with the underlying method's formal parameters, but it throws an IllegalArgumentException if a narrowing conversion would occur.
You can call Method#invoke but you will need the instance of the object you want to call the method on, from the method doc:
Invokes the underlying method
represented by this Method object, on
the specified object with the
specified parameters. Individual
parameters are automatically unwrapped
to match primitive formal parameters,
and both primitive and reference
parameters are subject to method
invocation conversions as necessary.
If the underlying method is static,
then the specified obj argument is
ignored. It may be null.
If the number of formal parameters
required by the underlying method is
0, the supplied args array may be of
length 0 or null.
If the underlying method is an
instance method, it is invoked using
dynamic method lookup as documented in
The Java Language Specification,
Second Edition, section 15.12.4.4; in
particular, overriding based on the
runtime type of the target object will
occur.
If the underlying method is static,
the class that declared the method is
initialized if it has not already been
initialized.
If the method completes normally, the
value it returns is returned to the
caller of invoke; if the value has a
primitive type, it is first
appropriately wrapped in an object.
However, if the value has the type of
an array of a primitive type, the
elements of the array are not wrapped
in objects; in other words, an array
of primitive type is returned. If the
underlying method return type is void,
the invocation returns null.
So the TL:DR is unless you have the actual object you want you call the method on, it is not possible.
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
Method m = ClassA.class.getMethod("foo", null);
instanceB.receiveMethod(m);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Class c = method.getDeclaringClass();
}
}
gives you the owning Class. An instance doesn't own methods.
You can do this, but the proper way in your example would be the use of an interface, because that seems to be what you want: You want to pass in an object that ClassB knows how to operate on.
interface Callback {
void foo();
}
public class ClassA implements Callback {...}
public class ClassB {
public void receiveMethod(Callback cb) {...}
}
This is like asking:
"Given an apple from an Apple orchard, which tree owns this apple?"
The answer to which is:
"No idea, since all apple trees produce apples, it could belong to any tree".
... in other words - you must supply an instance from which the method will be called
EDIT
From one of your comments, I gather you are looking for an alternative of the Observer pattern. You say you don't like the messiness of the Observer pattern and that it is not "generic" enough for you.
I would argue that it is probably one of the least messiest patterns in existence, AND interfaces are by definition as generic as things get!
So, perhaps its an implementation problem you're having. Luckily, I have already posted on SO an Observer implementation in JAVA, to demonstrate how powerful and elegant it is.
Polymorphism and Interfaces in Java (can polymorphism be used to implement interfaces...why?)
In fact: reflection is messier than using an interface, since you can't guarantee at compile time that the type of Object you are invoking an instance of a Method on, even supports that method! (without some error checking code). Versus with interfaces, its not possible to even have that problem.

Categories