Why can I not have a interface inside of a inner class? Why are they inherently static? Sorry if it's a stupid question, I've tried my best to google this again and again but I can't seem to wrap it around my head. As in why cannot I declare these in inner classes/local classes?
Also just as a confirmation, the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right? If we lose static and use just a final, we need a instance which makes no sense cause you can't instantiate a interface. Sorry, I really am confused, and I know I should just make another question but I think these two questions are somewhat related.
Think about what static means - "not related to a particular instance". So, as you point out, 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?
*Note, as #Owlstead points out, there are ways of defining interfaces within classes. But, for the purposes of wrapping your head around what an interface is (which seems to be what you're working on), I would ignore those possibilities for now as they distract from and possibly obscure the purpose of interfaces in general.
Why are they [interfaces] inherently static?
The difference between a static and a non-static nested class is in whether their instances have implicit references to enclosing instances (of the containing class), as well as to local variables from the containing scope. Before Java 8, there was no way for an interface to make use of such implicit references, because an interface could not initialize any non-static fields or provide any method implementations. (It still can't initialize non-static fields, though now it can provide default method implementations.) So before Java 8, there was no meaning in a non-static nested interface.
Also, from an implementation standpoint, these implicit references are implemented as an extra fields on the inner class, and they also require extra arguments to the inner-class constructor (in order to initialize these fields). Interfaces don't have fields, or constructors, so there's no way to implement this.
(Note: I don't usually recommend trying to understand language design decisions in terms of the implementation, because a single language feature can have many different correct implementations. But I think this is one case where understanding the implementation helps to understand the specification, hence the previous paragraph.)
Why can I not have a interface inside of a inner class?
Because interfaces are implicitly static: JLS §8.5.1:
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
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.
why cannot I declare these in inner classes/local classes?
Because they're implicitly static.
the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right?
Right.
If we lose static and use just a final, we need a instance
Right.
which makes no sense cause you can't instantiate a interface.
Yes you can. You can instantiate a class which implements the interface, or you can instantiate a method-local anonymous implementation of it. The real issue here is multiple inheritance of interfaces.
You cannot have an interface inside of an inner class because an inner class only exists within the context of an instance of an 'outer class'. Since this is the case, your interface would be de facto non-static.
You can, however have an interface inside of a nested class. See #owlstead answer. By placing the 'static' keyword on a the declaration of an 'inner class', it becomes a first class citizen, referencable from outside the outer class and (mostly) independent of the context of the outer class. Nested classes can be instantiated outside of the outer class; inner classes cannot.
After Java 16 release we can have static members inside Inner classes and static variables can be declared if they are final or effectively final. See this image
https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-8FD2B5E3-46C7-4C6C-8E8A-64AB49ABF855
Related
modifiers in variables in an interface are public, static, final by default. But how can I do if I want it to be private so that no other classes can call this variable
Declaring a class to implement an interface is a promise that this class provides these methods, or extensions thereof. Increasing/extending access to the methods is allowed, but decreasing access is not, because then we would break our promise.
This is similar to classes and extensions of them, subclasses. A subclass has to provide all methods of the superclass with at least the visibility they were declared with.
The reason for this is the statically typed nature of Java. If a type may differ from its initial declaration in such a way that it breaks (access to) the type, then it makes the whole static-typing obsolete.
Fields (also called member variables) are different in the way that their access cannot be extended. Declaring another member variable of similar name on a subclass is exactly that, another variable. By doing this, you hide the superclass' variable, and you may have to use the keyword super to access it.
The documentation for the anonymous classes states:
Anonymous classes also have the same restrictions as local classes with respect to their members:
You cannot declare static initializers or member interfaces in an anonymous class.
An anonymous class can have static members provided that they are constant variables.
I don't understand how would a static constant in an anonymous class be useful in practice. Static methods can't be overridden and we can't access the anonymous class's members from outside, therefore we don't need to use static constants.
Am I missing something or is it something that's not practical in any way, but it's permitted anyways?
You're missing:
Naming constants provide clarity to the programmers that needs to maintain the code.
Naming a constant allows it to be used in multiple places in the anonymous class code, making it easier to change later without missing a spot.
This is really no different than using private constants in any other class.
We use System.out.println without instantiating it or creating object of it. Same goes to Math class and many others (I guess). Is there something special about these classes? Can we use the classes and methods declared within those classes in same fashion? Please help.
You don't have to create objects for the System and Math classes because the methods and variables in those classes are static. This means that they belong to the class itself, not to instances of the class.
For reference see:
Understanding Class Members
Beyond Basic Arithmetic
This is something called 'static' method. In order to invoke static method, you do not need to have an instance of the class.
This also has other side effects such as non-existing 'this' and thus static methods cannot invoke instance methods.
This is mostly used for some sort of utility classes which are often stateless.
Math is a good example for it.
I suggest to read a bit about static methods and static in Java in general.
You don’t need to create object of System and Math class to use it because they have static methods. Static methods belong to the class and thus doesn’t require it to be instantiated.
Although, you can create its object and then also use those methods, but creating a class for static method is of no use.
Why don't we have to create object of System or Math classes in java and use them directly?
Because the methods of Math are declared as static methods, and because System.in / System.out / System.err are static variables.
Is there something special about these classes?
No. Any variables or methods that are declared as static will behave that way.
Can we use the classes and methods declared within those classes in same fashion?
I don't really understand what you are asking there. But, if you are asking if you can create an instance of Math or System so that you can do something like this:
Math myMath = new Math();
myMath.min(1, 2);
No, you can't. Neither of those classes has a public constructor, so you can't new them.
And if you could do that, it would be really bad style!
Reference:
Understanding Class Members
First,you cannot make an instance of the class Math,because it has only a single constructor and it's been marked private and you just can't make an instance of it from outside the class.
Snapshot of the source code of the class Math
Second,you don't need to do that.All of the methods in class Math are static,just use the class name and the dot operator and you can invoke any one of them.
System class can't instantiate/create object because this System class have private constructor.
And it's all members and methods are static, that can be accessible directly by Class name.
this simple and valid answer will help you.
We don't instantiate every other class or method because the JVM(Java Virtual Machine) already loads them into the project and hence, we can use these classes again and again. One such example is the main method. These classes/methods are already predefined for us so there is no need for us to instantiate such classes/methods because they are static.
You don't have to instantiate the object in order to use methods of the math class.
Because to use this methods we don't need object. We can directly invoke this.
These type of classes are called static. Here methods can directly invoked by the class itself.
They are already defined in the JVM. We don't need to instantiate to use methods of this class.
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
I have a class A. I define another class B within a method (even main) of the class A and class B can access all the variables within the scope of the method it is defined in. What is the terminology for such classes (as B)? Some people have been saying Nested classes or Inner classes but IIRC, those are the classes where they have another class as their data members (kinda like composition in C++).
The second part of my question is that some people have been saying that when you have a class defined within a method of another class, then the variables of the first class (A) that are accessed by the later class (B) need to be declared final. Is this to be followed strictly and why so?
According to the Java Language Specification these are "local classes":
A local class is a nested class (§8 (Classes)) that is not a member of
any class and that has a name (§6.2, §6.7).
or "anonymous [inner] classes", which are just the ones that don't have a name (e.g. Interface x = new Interface() { ...).
These are special cases of inner classes which is generally what I've heard people refer to them as.
As for your second question, "Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted." So it is a compile-time error if you try to access non-final local variables. Obviously this part must be followed strictly if you want your class to compile.
I have not personally heard the advice that you should not access non-final fields of the enclosing class, and I'm pretty sure it's allowed. While arguments could be made that fields should be final unless they can't be, I don't see any stylistic reason this should be more important in inner classes. There is a technical difference that accessing a field from an inner class may cause the compiler to create and call synthetic getters and setters, but this is generally a minor performance concern.