Are there any limitations when using anonymous classes with Java's functional interfaces?
Can an anonymous class access private members of the enclosing class?
How can anonymous classes help in GUI programming?
The most minimal example:
interface Foo {}
public static void main (String[] args)
{
Foo foo = new Foo() {};
}
Literally a declaration of an interface, and then usage as an anonymous class with no additional declarations.
Practically speaking, it does nothing. However, as we add bits in:
interface Foo {
public void bar();
}
public static void main (String[] args) throws java.lang.Exception
{
Foo foo = new Foo() {
public void bar() {
System.out.println("Hello");
}
};
}
It becomes a full-fledged helper class for our method.
The most common use for early/mid level programming would be overriding Listeners to do specific actions. We know the Listener is listening for something, and we want it to do something as a result of the Listener, so we craft the Listener and say "Do this when you are triggered."
Here's the example of a really complex ActionListener tutorial: https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
But typically, if it's something that's mundane like "run a method on click", you'll use an anonymous in-line declaration that just calls a method for you.
I suppose the "absolute minimal requirement" to create an anonymous class is to have a place in your code that requires an instance of a non-final class or interface of some kind.
Meaning, if I have a method in MyClass:
public static void gimmeMyObject(MyObject c)
I can define an anonymous class that extends MyObject as long as MyObject is not final:
//Somewhere in a method
MyClass.gimmeMyObject(new MyObject() {
public String myMethod() {
return "I'm anonymous";
}
});
That anonymous class will be passed in as a MyObject.
However, I could not do this if the method required a String or Integer, for example, because those are final classes.
For the above example, the non-anonymous class would translate to:
public class MyAnonObject extends MyObject { //In actuality, an anonymous class doesn't have a name, though.
public String myMethod() {
return "I'm anonymous";
}
}
Your question is a little confusing, but it sounds like you want a class that both extends Thread and implements some interface, but which can't be accessible outside of the method it's being used by (which would rule out even private nested classes). In that case use a local class:
void myMethod() {
class Impl extends Thread implements SomeInterface {
@Override
public void someInterfaceMethod(String s){ }
}
new Impl().someInterfaceMethod("data");
}
EDIT: In response to your update, you can naturally give the local class a constructor and pass in data, or just let it close over final variables in the outer method.
if i can't syntactically do this, can anyone explain the logic/implementation design that of why this would never work?
I can explain. If you have an expression foo.bar(...) in Java, the compiler must make sure that the static (compile-time) type of the expression foo supports the method bar(). In your first case, the expression on the left is the anonymous class creation expression, so its static type is the anonymous class which has the method.
However, in your second case, the expression on the left is a variable. The static type of a variable is the type that the variable was declared with. In Java, variables must be declared with an explicit type (no var or auto like some other languages). Therefore, its static type must be a named type. Thread and no other named type supports the method NoNoYouCantCallMe(); only the anonymous class supports this method, and you can't declare a variable of anonymous class type. That's why it is not syntactically possible.
However, I would like simply like to pass some data to this anonymous class only once (ideally the constructor, but you will notice that you can't actually override the constructor in Thread()).
This is simple. You don't need to explicitly pass data into the anonymous class, because inside anonymous classes and local classes you automatically have access to final variables from the surrounding scope. So instead of passing data in, you just directly use data from the outside.
final String someData = "blah";
Thread t = new Thread() {
public void run() { doStuffWith(someData); }
};