On the subject of Anonymous classes, the Oracle documentation states that...
They are like local classes except that they do not have a name. Use them if you need to use a local class only once
Now, given that local classes are (to my knowledge) classes defined within a method (or some other local construct) like the following...(where 'MyInterface' is an interface with an abstract 'test' method)
public void localTest(){
MyInterface mi = new MyInterface(){
#Override
public void test(){System.out.println("test");};
};
}
The above is OK and falls within the definition above, however, I can also define the following...
class MyClass{
MyInterface mi = new MyInterface(){
#Override
public void test(){System.out.println("test");};
};
}
This isn't within a method so isn't a 'Local' class and therefore doesn't fall within the above definition. Is there anywhere I can read about these types of anonymous classes (anonymous member classes if you will). What exactly are they if not anonymous classes as defined?
Both examples you show are anonymous classes. A true local class is a class definition in a method (or other code block), with an actual name (so, not anonymous). Given your example, an equivalent local class would be:
public void localTest(){
class LocalClass implements MyInterface {
#Override
public void test(){
System.out.println("test");
}
}
MyInterface mi = new LocalClass();
}
In my opinion you should hardly ever need a local class. I think I have only tried to use it once, to only quickly refactor it when I got a grip on what I actually needed.
The most important difference between local classes and anonymous classes is that you can reuse a local class within the same method (that is create multiple instances in the same method; without resorting to loops or lambdas).
Furthermore, as you actually have class definition, you can also define and call methods that aren't defined in the interface or super-class. Prior to Java 10 and the introduction of var, this was not possible with anonymous classes.
Other minor differences are that local classes can be abstract or final, and local classes can extend (and be extended by) other local classes, while an anonymous class is not final and cannot be abstract, but anonymous classes cannot be extended by other classes.
For more information regarding the difference between local classes and anonymous classes, see the Java Language Specification, specifically 14.3. Local Class Declarations and 15.9.5. Anonymous Class Declarations and related sections.
Local classes are defined here as being defined in a block, rather than in a method. Your example is still an anonymous class. If you're in the process of learning, a note here is that you can actually replace the declaration with a lambda expression like so:
MyInterface mi = () -> System.out.println("test");
Also, anonymous classes are only described as being like local classes, meaning that the former is not necessarily a subset of the latter.
Related
I have just found a static nested interface in our code-base.
class Foo {
public static interface Bar {
/* snip */
}
/* snip */
}
I have never seen this before. The original developer is out of reach. Therefore I have to ask SO:
What are the semantics behind a static interface? What would change, if I remove the static? Why would anyone do this?
The static keyword in the above example is redundant (a nested interface is automatically "static") and can be removed with no effect on semantics; I would recommend it be removed. The same goes for "public" on interface methods and "public final" on interface fields - the modifiers are redundant and just add clutter to the source code.
Either way, the developer is simply declaring an interface named Foo.Bar. There is no further association with the enclosing class, except that code which cannot access Foo will not be able to access Foo.Bar either. (From source code - bytecode or reflection can access Foo.Bar even if Foo is package-private!)
It is acceptable style to create a nested interface this way if you expect it to be used only from the outer class, so that you do not create a new top-level name. For example:
public class Foo {
public interface Bar {
void callback();
}
public static void registerCallback(Bar bar) {...}
}
// ...elsewhere...
Foo.registerCallback(new Foo.Bar() {
public void callback() {...}
});
The question has been answered, but one good reason to use a nested interface is if its function is directly related to the class it is in. A good example of this is a Listener. If you had a class Foo and you wanted other classes to be able to listen for events on it, you could declare an interface named FooListener, which is ok, but it would probably be more clear to declare a nested interface and have those other classes implement Foo.Listener (a nested class Foo.Event isn't bad along with this).
Member interfaces are implicitly static. The static modifier in your example can be removed without changing the semantics of the code. See also the the Java Language Specification 8.5.1. Static Member Type Declarations
An inner interface has to be static in order to be accessed. The interface isn't associated with instances of the class, but with the class itself, so it would be accessed with Foo.Bar, like so:
public class Baz implements Foo.Bar {
...
}
In most ways, this isn't different from a static inner class.
Jesse's answer is close, but I think that there is a better code to demonstrate why an inner interface may be useful. Look at the code below before you read on. Can you find why the inner interface is useful? The answer is that class DoSomethingAlready can be instantiated with any class that implements A and C; not just the concrete class Zoo. Of course, this can be achieved even if AC is not inner, but imagine concatenating longer names (not just A and C), and doing this for other combinations (say, A and B, C and B, etc.) and you easily see how things go out of control. Not to mention that people reviewing your source tree will be overwhelmed by interfaces that are meaningful only in one class.So to summarize, an inner interface enables the construction of custom types and improves their encapsulation.
class ConcreteA implements A {
:
}
class ConcreteB implements B {
:
}
class ConcreteC implements C {
:
}
class Zoo implements A, C {
:
}
class DoSomethingAlready {
interface AC extends A, C { }
private final AC ac;
DoSomethingAlready(AC ac) {
this.ac = ac;
}
}
To answer your question very directly, look at Map.Entry.
Map.Entry
also this may be useful
Static Nested Inerfaces blog Entry
Typically I see static inner classes. Static inner classes cannot reference the containing classes wherease non-static classes can. Unless you're running into some package collisions (there already is an interface called Bar in the same package as Foo) I think I'd make it it's own file. It could also be a design decision to enforce the logical connection between Foo and Bar. Perhaps the author intended Bar to only be used with Foo (though a static inner interface won't enforce this, just a logical connection)
If you will change class Foo into interface Foo the "public" keyword in the above example will be also redundant as well because
interface defined inside another interface will implicitly public
static.
In 1998, Philip Wadler suggested a difference between static interfaces and non-static interfaces.
So far as I can see, the only difference in making an
interface non-static is that it can now include non-static inner
classes; so the change would not render invalid any existing Java
programs.
For example, he proposed a solution to the Expression Problem, which is the mismatch between expression as "how much can your language express" on the one hand and expression as "the terms you are trying to represent in your language" on the other hand.
An example of the difference between static and non-static nested interfaces can be seen in his sample code:
// This code does NOT compile
class LangF<This extends LangF<This>> {
interface Visitor<R> {
public R forNum(int n);
}
interface Exp {
// since Exp is non-static, it can refer to the type bound to This
public <R> R visit(This.Visitor<R> v);
}
}
His suggestion never made it in Java 1.5.0. Hence, all other answers are correct: there is no difference to static and non-static nested interfaces.
In Java, the static interface/class allows the interface/class to be used like a top-level class, that is, it can be declared by other classes. So, you can do:
class Bob
{
void FuncA ()
{
Foo.Bar foobar;
}
}
Without the static, the above would fail to compile. The advantage to this is that you don't need a new source file just to declare the interface. It also visually associates the interface Bar to the class Foo since you have to write Foo.Bar and implies that the Foo class does something with instances of Foo.Bar.
A description of class types in Java.
Static means that any class part of the package(project) can acces it without using a pointer. This can be usefull or hindering depending on the situation.
The perfect example of the usefullnes of "static" methods is the Math class. All methods in Math are static. This means you don't have to go out of your way, make a new instance, declare variables and store them in even more variables, you can just enter your data and get a result.
Static isn't always that usefull. If you're doing case-comparison for instance, you might want to store data in several different ways. You can't create three static methods with identical signatures. You need 3 different instances, non-static, and then you can and compare, caus if it's static, the data won't change along with the input.
Static methods are good for one-time returns and quick calculations or easy obtained data.
How can the method getSequencer in JavaSound API return an instance of the interface Sequencer?
Sequencer sequencer=MidiSystem.getSequencer();
I have read that we cant create an instance of an interface.
static is a very troublesome concept at best, its greatest akin for trouble at explaining is "volatile" keyword declaration.
You would have less trouble with "synchronized" keyword on a code block than the previous two for explaining their usage parameters and concept!
"static" is not constructed as "new" because it is not a "separate instance" it is already available when compiled in as a static object.
All interfaces in Java are abstract but have "static" fields(variables) only,
ONLY ONE of those loaded static class instruction version of AKA(A Kind of Alias) "instance" of a class(or alternately interface) will be present at that class hierarchy level on the process in the JVM runtime in that particular "user classes" hierarchy structure of call for any number of classes created that commit call of a static object or a static method (static code DOES NOT MAKE A NEW SEPARATE SET OF INSTRUCTION IF CALLED CONCURRENTLY FROM VARIOUS CLASS COPIES).
With anything "static" there is only one copy in use for all of the program at that calling class on the PID process level in the JVM during runtime.
You cannot instantiate MidiSystem because all its methods are "static"
So to use ANY static class to call one of its static methods from it (or the same on an interface)
you only use its class name followed by the dot operator on its method you wish to call.
Exactly as you have it in the code and syntax you posted. (NOTE "Sequencer" is actually static )
But if you need your variable non static to remove static you cast it if the class type to cast to is non static, only if the class you are casting is not itself an actual "static" compiled class !
e.g. DriverManager.getDriver() for JDBC database running more than one connection concurrently cannot use static driver copies or there would only be one copy available in use of during runtime with the instructions template (the class byte code for the static class) !
To remove "static" from an object, the object must be cast to non static into a variable of same object type that is not of static notation(declared).
// the getDriver() method is static inside class DriverManager ,
// Driver is an Interface not a class
Driver driver = (Driver) DriverManager.getDriver( configuration.jdbcUrl() );
// After casting, there is now a separate non static reference of Driver
// interface , so **note that neither MidiSystem or DriverManager class are**
// actually declared static and both have no constructor and not declared
// abstract but contain only static methods !
an "INSTANCE" is something you construct , so another one is a new instance !
Interfaces are not constructed, they operate much more alike "abstract" and "static" declarations.
Using the class name only is the syntax of calling EITHER abstract or static classes to obtain their methods.
A final point , to refer to an interface as a "data type" is to make a reference variable to represent it because an interface IS a data type (known as an object) the same as a class or abstract class.
So your above code has "Sequencer" interface as a data type.
When a class "implements" an interface the class itself can be cast to that interface because it is ALSO that object type.
e.g.
public class Example implements Extra{.....}
Extra example = (Extra)new Example();
// next below shorthand implicit cast is compiler dependent
public class Example implements Extra{.....}
Extra example = new Example();
If you do not implement an interface in a class the interface can be called into the code with assignment of a reference variable by using a class that has a method that obtains that interface data type.
There is a huge relationship between abstract classes and interfaces but they are not the same.
Abstract classes do not have global variables.
Interfaces do have global variables but all of them must be static and final. Abstract classes cannot have any global variables or it would be an "instance of a class" and would then require to be constructed as "new".
Abstract classes have less strict rules on method declaration than interfaces.
Abstract classes can have most class modifiers interfaces are all public
Interfaces have "default" modifier for methods that contain an implementation body of code or must be static method.
In short the variable for Sequencer interface is not an instance variable, it is a reference and (clause for static) you are referring to something defined as "static" so IT MUST be there when the class that calls it starts !
You cannot declare an interface inside a block like below
public void greetInEnglish() {
interface HelloThere {
public void greet();
}
class EnglishHelloThere implements HelloThere {
public void greet() {
System.out.println("Hello " + name);
}
}
HelloThere myGreeting = new EnglishHelloThere();
myGreeting.greet();
}
In This Oracle tutorial I got "You cannot declare member interfaces in a local class." because "interfaces are inherently static."
I am eagar to understand this with more rational information, why and how interface are inherently static?
and why above code does not make sense?
Thanks in advance to elloborate!
I am eagar to understand this with more rational information, why and
how interface are inherently static?
because interfaces are implicitly static, and you can't have non-final statics in an inner class.
Why are they implicitly static?
because that's the way they designed it.
and why above code does not make sense?
because of the above reason ,
Now lets make it simple :
What static means - "not related to a particular instance". So, suppose, a static field of class Foo is a field that does not belong to any Foo instance, but rather belongs to the Foo class itself.
Now think about what an interface is - it's a contract, a list of methods that classes which implement it promise to provide. Another way of thinking about this is that an interface is a set of methods that is "not related to a particular class" - any class can implement it, as long as it provides those methods.
So, if an interface is not related to any particular class, clearly one could not be related to an instance of a class - right?
I also suggest you to study Why static can't be local in Java?
Any implementations can change value of fields if they are not defined as final. Then they would become a part of the implementation.An interface is a pure specification without any implementation.
If they are static, then they belong to the interface, and not the object, nor the run-time type of the object.
An interface provide a way for the client to interact with the object. If variables were not public, the clients would not have access to them.
Your code does not make sense because you define the interface within the body of a method. You can define an interface either at top level or in another class or interface.
You cannot declare an interface inside a block
reference
I've been wondering why it's allowed to do a code implementation in an interface, when interfaces are suppossed to contain no code implementation:
public interface someInterface{
String someString = "example";
}
I can make a class implement this interface, without getting an error:
public class someClass implements someInterface
How come?
You are allowed to declare constants in interfaces, which is what you have done. You have not implemented code.
Variables declared in interfaces are implicitly declared public static final.
The JLS, Section 9.3, covers this:
Every field declaration in the body of an interface is implicitly
public, static, and final. It is permitted to redundantly specify any
or all of these modifiers for such fields.
According to java docs
Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
Here you are not defined any methods to implement.So you didn't get any error here.
There is no strict condition that an interface must have signatured methods.Remember there are Marker Interfaces too in java.
And secondly , You can declare variables inside interface.
And that variable someString assigned in a static context and shared across all the implemntations by that interface
Point is that the variables inside declared interface are implicitly static and final.You can use them.
I want to create a class, ClassB, as inner class of ClassA, but I want to write down outside ClassA.java file.
How can I do this?
It will be a lot of inner class, and ClassA.java file will be enormous.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
Thanks.
The simple answer, is no you cannot.
By virtue of being an inner class, the class has to be inside the scope of the parent class.
If your class is really going to be enormous, it probably says something about the design of your class. Are you making proper use of encapsulation?
Put all your classes in a package and define the classes to be package private.
package com.example.here
class Hello{
//...
}
Notice the absence of the keyword public? You will only be able to create an instance of the class Hello if the class creating it is in the com.example.here package.
Try the following ...
Hand over a reference of the outer-class to the no-longer-inner-class
Use packages and make the no-longer-inner-class package-private (Jeremy's answer)
In the very rarest of cases, it might actually be best to go with inner classes, and at the same time have them do work elsewhere. If this really is you, please read on ...
How to keep inner classes small
a) Extend from outer classes
class Outer {
class SomeInnerClass extends SomeClass {
// More specific code here
}
}
class SomeClass {
// A lot of generic code here (in a different file)
}
b) Use abstract methods
One of the (more correct) reasons for using inner classes, usually has to do with the use of the exact instance of the outer-class. To tackle it in a generic fashion in the base class, use abstract getters.
abstract class SomeClass {
protected abstract SpecificData getSpecificData();
void someMethod() {
SpecificData specificData = getSpecificData();
// Do work with the "specific data" here ...
}
}
class Outer {
private SpecificData mSpecificData = new SpecificData();
class SomeInnerClass extends SomeClass {
#Override
protected SpecificData getSpecificData() {
return OuterClass.mSpecificData;
}
}
}
I think you get the idea, ... You might also consider using some GeneralData class or interface (within SomeClass) instead, and have getSpecificData() return a more specific (descended-)instance of it.
Again: This can be terribly misused to create very bad unreadable code, but it also can be used for very nice patters under the right circumstances, anyways it should answer the original question.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
If you want to restrict access to a single class, you can put them all in a new package. You will need to move the designated class that is allowed access into this packate, too. For the new classes, you can restrict access by using the default access level (no public/private/protected modifier). This will make them accessible only to the classes in their package. The specified class that is allowed access can be made public so that it can be used outside this new package.
Note: You have the option of restricting the visibility of the class or the visibility of the constructor.