compile fail when changing inner class to static - java

On changing non-static inner class to static why there are compile time error on running code says-
Illegal enclosing instance specification
public class TestingInnerStatic{
public static void main(String args[]) {
InnerSame innerSame = new TestingInnerStatic().new InnerSame();//compile fail
Outer.InnerDiff innerDiff = new Outer().new InnerDiff();//compile fail
}
public void main() {
InnerSame innerSame = new InnerSame();
Outer.InnerDiff innerDiff = new Outer().new InnerDiff();//compile fail
}
static class InnerSame{}
}
class Outer{
static class InnerDiff{}
}
take a example of other member,this is only a convention and a good practice to call a static member on reference of class but if U call them on object they works not show compile fail.So why there is a compile fail?

If an inner class is non-static then you require an instance of the outer class to make an instance of the inner class. But that is not the case for static classes, an instance of an inner static class can exist without an instance of the outer class.
static example:
InnerClass ic = new Outer.InnerClass();
Notice I am not making a new instance of the outer class.
EDIT: reference

Related

Why we can not make an instance of inner class inside the main method of outer class in regular way?

I know how to make an instance of an inner class. But I want to know why we can not do that in the following way:
class outerclass{
public static void main(String[] args){
innerclass in=new innerclass();
}
class innerclass{
}
}
If I do this then I get the following error:
No enclosing instance of type outerclass is accessible. Must qualify the allocation with an enclosing instance of type outerclass (e.g. x.new A() where x is an instance of outerclass).
Why?
class Demo{
public static void main(String[] args){
System.out.println(innerclass.a);
}
static class innerclass{
static int a=1;
}
}
Gives the output 1.
See here while making the inner class as static You can easily access in your outer class,In order to create an instance of the Nested class you must reference it by prefixing it with the Outer class name, like this:
Outer.Nested instance = new Outer.Nested();
Non-static Nested Classes (Inner Classes)
Non-static nested classes in Java are also called inner classes. Inner classes are associated with an instance of the enclosing class. Thus, you must first create an instance of the enclosing class to create an instance of an inner class. Here is an example inner class definition:
public class Outer {
public class Inner {
}
}
Here is how you create an instance of the Inner class:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
Notice how you put new after the reference to the outer class in order to create an instance of the inner class.
Non-static nested classes (inner classes) have access to the fields of the enclosing class, even if they are declared private. Here is an example of that:
public class Outer {
private String text = "I am private!";
public class Inner {
public void printText() {
System.out.println(text);
}
}
}
Your innerclass is not static. This means it must have a reference to the outerclass. main is static and has no implicit outerclass.
The simple solution is to make your inner class a static nested class.
You must either make your inner class static (as already mentioned) or create your inner class from a non-static context, e.g. from a non-static method.
I.e. either this:
class outerclass{
void myMethod() {
innerclass in = new innerclass();
}
class innerclass{
}
}
or this
class outerclass{
public static void main(String[] args){
innerclass in=new innerclass();
}
static class innerclass{
}
}
outerclass thats encapsulates innerclass is not instantiated, hence, calling innerclass directly would throw an error since there is no outerclass to attach innerclass.
Therefore as suggested by the previous answers, making innerclass static would resolve the problem, allowing access to the innerclass without instantiation.
There are lot of existing answers with regards to this topic. A quick google brings this up.
Java - No enclosing instance of type Foo is accessible

Non static inner class object creation without explicit enclosing instance

I read that an instance of an inner class cannot be created without an instance of outer class. But when I tried to create an instance of my inner class using it as an instance member of my outer class, it worked.
I understand that it is creating an inner object through a reference to my outer class object, but is it the right way to do it?
Below is my code snippet:
public class TestInner {
private Nonstatic non = null;
private static int access = 4;
public class Nonstatic {
void hello() {
access = 90;
}
}
public static void main(String[] args) {
TestInner outer = new TestInner();
TestInner.Nonstatic innern= outer.new Nonstatic();
System.out.println("Non static obj1 is "+innern);
outer.testinnerObj();
}
public void testinnerObj() {
non = new Nonstatic();
System.out.println("Non static obj2 is "+non);
non.hello();
}
}
You're writing "An instance of Inner class cannot be created without an instance of outer class". And that's exactly what you are doing.
First, you create an instance of the "outer" class:
TestInner outer = new TestInner();
Then, you create an instance of the "inner" class - it only lives
in the scope of outer:
TestInner.Nonstatic innern= outer.new Nonstatic();
So, the question maybe boils down to this: yes, you are creating the object in the static main method. But that does not matter, because you are using the syntax outer.newwhich creates it in the scope of outer.
Hope that helps.

Does a constructor of private class has to be private?

If a class is private then must the constructor be private as well?
No, there is no such restriction. See JLS ยง8.8.3. Constructor Modifiers.
It's worth pointing out that only a nested class can be declared private. The JLS permits the constructors for such a class to use any valid access modifiers.
If you mean nested class, the answer is no. Making the inner class private makes it only usable within the outer class.
Edit: It appears that outer classes have full access to the innards of the inner classes regardless of their access modifiers. This invalidates my above reasoning, but regardless, there is no such restriction. Curiously though, now it appears that if the inner class is private, its constructor is essentially private, regardless of its access modifier, since noone else can call it.
No it hasn't. On the contrary, if you create an instance of the inner class using a private constructor (which is default for a private class) from the outer class Java will create an additional class to prevent access violation and keep JVM happy
If you compile this class
class Test {
private class Test2 {
Test2() {
}
}
Test() {
new Test2();
}
}
javac will create Test.class, Test#Test2.class
and if you compile this class
class Test {
private class Test2 {
}
Test() {
new Test2();
}
}
javac will create Test.class, Test#Test2.class, Test$1.class
No it is not fix, you can set it private/public/any you want.
But in some case I prefer to make constructor private, when you don't want to allow other classes to create object of this class. then in that case you can do something like this, by setting constructor private.
private class TestClass{
private TestClass testClass=null;
private TestClass(){
//can not accessed from out side
// so out side classes can not create object
// of this class
}
public TestClass getInstance(){
//do some code here to
// or if you want to allow only one instance of this class to be created and used
// then you can do this
if(testClass==null)
testClass = new TestClass();
return testClass;
}
}
Btw it depends on your requirement.
It does not have to be private. But it can. Example:
public class Outer {
// inner class with private constructor
private class Inner {
private Inner() {
super();
}
}
// this works even though the constructor is private.
// We are in the scope of an instance of Outer
Inner i = new Inner();
// let's try from a static method
// we are not in the scope of an instance of Outer
public static void main(String[] args) {
// this will NOT work, "need to have Inner instance"
Inner inner1 = new Inner();
// this WILL work
Inner inner2 = new Outer().new Inner();
}
}
// scope of another class
class Other {
// this will NOT work, "Inner not known"
Inner inner = new Outer().new Inner();
}
It doesn't make a difference if you use private or public constructor on private inner classes. The reason is that the inner class instance is part of the outer class instance. This picture says it all:
Note that we are talking about an inner class. If the nested class was static, the official terminology is static nested class, which is different from an inner class. A public static nested class would be accessible without outer class instance just by calling new Outer.Inner(). See here for more information about inner- and nested classes. http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Why instantiation of static nested class object is allowed?

I have started learning Java language for Android Application developement.
As per my understanding based on static class, we cannot instantiate object of static class.
But why instantiation of static nested class object is allowed in following situaltion?
class EnclosingClass
{
//...
class static StaticInnerClass
{
//...
}
}
Why we can create object of inner class if it is marked as static?
EnclosingClass.StaticInnerClass s = new EnclosingClass.StaticInnerClass()
As per my understanding based on static class, we cannot instantiate object of static class.
Your understanding of the meaning of "static class" is incorrect. Basically a "static class" in Java is a nested class which doesn't have an implicit reference to an instance of the containing class. See section 8.5.1 of the JLS for more information, in particular:
The static keyword may modify the declaration of a member type C within the body of a non-inner class or interface T. Its effect is to declare that C is not an inner class. Just as a static method of T has no current instance of T in its body, C also has no current instance of T, nor does it have any lexically enclosing instances.
Perhaps you were thinking of static classes in C#, which are completely different?
Why we can create object of inner class if it is marked as static?
You may need to use a nested class in a static context, for example:
public class Test {
public static void main(String args[]) {
InnerClass innerClass = new InnerClass();
}
class InnerClass {
}
}
In this case, when you try to instantiate the innerClass you get the error:
No enclosing instance of type Test is accessible. Must qualify the
allocation with an enclosing instance of type Test (e.g. x.new A()
where x is an instance of Test).
To avoid this, you could instantiate an object of type Test and create an instance of innerClass from it:
Test test = new Test();
InnerClass innerClass = test.new InnerClass();
or better, declare also the innerClass as static and instantiate it in a static context:
public class Test {
public static void main(String args[]) {
InnerClass innerClass = new InnerClass();
}
static class InnerClass {
}
}
check it, maybe it can help you
Nested Classes

Must the inner class be static in Java?

I created a non-static inner class like this:
class Sample {
public void sam() {
System.out.println("hi");
}
}
I called it in main method like this:
Sample obj = new Sample();
obj.sam();
It gave a compilation error: non-static cannot be referenced from a static context When I declared the non-static inner class as static, it works. Why is that so?
For a non-static inner class, the compiler automatically adds a hidden reference to the "owner" object instance. When you try to create it from a static method (say, the main method), there is no owning instance. It is like trying to call an instance method from a static method - the compiler won't allow it, because you don't actually have an instance to call.
So the inner class must either itself be static (in which case no owning instance is required), or you only create the inner class instance from within a non-static context.
A non-static inner class has the outer class as an instance variable, which means it can only be instantiated from such an instance of the outer class:
public class Outer{
public class Inner{
}
public void doValidStuff(){
Inner inner = new Inner();
// no problem, I created it from the context of *this*
}
public static void doInvalidStuff(){
Inner inner = new Inner();
// this will fail, as there is no *this* in a static context
}
}
An inner class needs an instance of the outer class, because there is an implicit constructor generated by compiler. However you can get around it like the following:
public class A {
public static void main(String[] args) {
new A(). new B().a();
}
class B {
public void a() {
System.err.println("AAA");
}
}
}
Maybe this will help : http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
the non-static inner class cannot be called in a static context (in your example there is no instance of the outer class).

Categories

Resources