Why its saying
error No enclosing instance of type Demo is available due to some intermediate constructor invocation
class Demo {
class DemoInner{
DemoInner(){
System.out.println("DemmoInner");
}
}
}
public class Noding extends Demo.DemoInner{
Noding(){
super();
System.out.println("Noding");
}
public static void main(String[] args) {
new Noding();
}
}
Noding is a child of Demo.DemoInner and Demo.DemoInner is an instance thing of Demo class.
So while creating Child class Noding instance, calling super should not be giving a problem becasue parent should be in existence before creating child. And in this case parent is Demo.DemoInner for Noding and Demo.DemoInner can't exist without Demo.
So why its giving error while calling super() in Noding constructor ?
The call to the inner class is called like this:
class Noding extends Demo {
public static void main(String[] args) {
Demo demo = new Demo();
Demo.DemoInner inner = demo.new DemoInner();
System.out.println(inner);
}
}
Unless it is declared as static, it is dynamic, that is the object needs to be instantiated.
If you declared DemoInner like this:
class Demo {
class DemoInner{}
}
It means DemoInner class is one of the instances of Demo. So when you use DemoInner class, you need to instantiate Demo class first. And access DemoInner as the Demo instance's member object (see #AlexeyKonovalov's answer).
Or a workaround is to make DemoInner static (as #RobOhRob commented). Once declared static, it is no longer a member object of the outer class Demo object. You can access DemoInner class whether the outer class is instantiated or not.
class Demo {
static class DemoInner{}
}
Making DemoInner as a static class shall make the code run. DemoInner is a non-static inner class and hence it is associated with the instance of Demo class.
You can't call its constructor from Noding without making the class static.
class Demo {
static class DemoInner{
DemoInner(){
System.out.println("DemmoInner");
}
}
}
public class Noding extends Demo.DemoInner{
Noding(){
super();
System.out.println("Noding");
}
public static void main(String[] args) {
new Noding();
}
}
Related
I have a very simple class which I want to use as a subclass of another one. But when I put its code in the parent's class I get :
non-static variable this cannot be referenced from a static context
On the other hand when I put the sublass GenTest's class code outside the the "parent's" class code - JavaApp1 I do not get this error.
public class JavaApp1 {
class GenTest {
#Deprecated
void oldFunction() {
System.out.println("don't use that");
}
void newFunction() {
System.out.println("That's ok.");
}
}
public static void main(String[] args) {
GenTest x = new GenTest();
x.oldFunction();
x.newFunction();
}
}
Why is this happening ?
Your nested class (which isn't a subclass, by the way) isn't marked as being static, therefore it's an inner class which requires an instance of the encoding class (JavaApp1) in order to construct it.
Options:
Make the nested class static
Make it not an inner class (i.e. not within JavaApp1 at all)
Create an instance of JavaApp1 as the "enclosing instance":
GenTest x = new JavaApp1().new GenTest();
Personally I'd go with the second approach - nested classes in Java have a few oddities around them, so I'd use top-level classes unless you have a good reason to make it nested. (The final option is particularly messy, IMO.)
See section 8.1.3 of the JLS for more information about inner classes.
It should be static class GenTest, as you create an instance of it from static method.
Also, in general, inner classes should be static.
The class GenTest is a non-static class and therefore must be instantiated within an instance of JavaApp1. If you do static class GenTest what you have work otherwise you need to create an instance of JavaApp1 and create the GenTest within a non-static method.
Thar's because GenTest is defined withing the context of JavaApp1. So you can refer to it unless you have an instance of JavaApp1. Change it to a static class for it to work.
static class GenTest...
Please Use
static class GenTest()......
The way you are invoking isn't the correct way to do that. Since the inner class GenTest is a member of the JavaApp1 the correct way to invoke it would be
GenTest x = new JavaApp1().new GenTest();
Using it your class would compile correctly.
The class is nested which means that your nested class is not static, which means you have to create an object for the nested class through the object of the main class. what that means is your psvm should be like this.
public static void main(String[] args) {
JavaApp1 a=new JavaApp1(); //create an object for the main class
JavaApp1.GenTest x=a.new GenTest();
x.oldFunction();
x.newFunction();
}
class Test {
static class GenTest { // nested class with static
static void oldFunction() { // static method
System.out.println("don't use that");
}
void newFunction() { // non-static method
System.out.println("That's ok.");
}
}
public static void main (String[] args) {
GenTest.oldFunction(); // call static method
GenTest two = new GenTest(); // call non-static method
two.newFunction();
}
}
Java Online
java
Hi i have a Base class containing one string member as belows :
public class BaseClass
{
public String test;
}
Child class extending base class where i wish to initialize the test value.
public class ChildClass extends BaseClass
{
public void initialize()
{
System.out.println("inside constructor of ChildClass.");
this.test="stringtest";
}
}
Test class where i wish to use the value of test variable of base class:
public class TestClass extends BaseClass
{
public void test()
{
new ChildClass().initialize();
System.out.println(this.test);
}
public static void main(String[] args) {
new TestClass().test();
}
}
Now my above code is printing null inside test class. why so? although i have initialized the test variable in child class? am i going wrong somewhere in java concepts?
the problem is that you create new ChildClass but you aren't setting it in a variable. then you print this.test which is never set.
when you are in test method you are in TestClass instance:
you are creating and setting a ChildClass class
but then you are printing the TestClass test member
if you just want to create ChildClass and use it do
public class TestClass
{
public void test()
{
ChildClass cls =new ChildClass().initialize();
System.out.println(cls.test);
}
public static void main(String[] args) {
new TestClass().test();
}
}
or if you want to extend ChildClass do
public class TestClass extends BaseClass
{
public void test()
{
initialize();
System.out.println(this.test);
}
public static void main(String[] args) {
new TestClass().test();
}
}
new ChildClass() and new TestClass() are 2 different objects even if they are extending common BaseClass.
Having a common BaseClass as super class doesn't mean that it shares the non static fields of it, with all the instances of its different subclasses
This would have worked if test was static (shared class field) in BaseClass
There are two instances of BaseClass in the example you posted. One is the one instantiated with new ChildClass() and the other one is instantiated by the main() method (TestClass). Each one of them, being a subclass of BaseClass, has its own test member (they are different variables with different values).
Remember that the this keyword always references the instance in which it is used.
In this case, System.out.println(this.test); is accessing the test property of the TestClass instance created in the main method.
You need to access the test property of the other instance. You could do so by keeping a reference to the ChildClass instance and accessing the test property afterwards:
ChildClass instance = new ChildClass().initialize();
System.out.println(instance.test);
You might find the following Java Tutorials page useful: Using the this Keyword.
Also take into account that TestClass doesn't need at all to extend BaseClass. You could keep accessing instance.test because it is a public member, but you should consider making the field private and provide getter and setter methods. See the following question for relevant information on this: Why use getters and setters?
You need a instance of Child Class
ChildClass cls =new ChildClass().initialize();
System.out.println(cls.test);
this is referring to the Test Class instance.
Consider the following program:
public class A
{
public static void main(String[] args)
{
class B
{
private B()
{
System.out.println("local");
}
}
// how are we able to create the object of the class having private constructor
// of this class.
B b1= new B();
System.out.println("main");
}
}
Output:
local
main
A class having private constructor means we can create object inside the class only, but here am able to create instance outside the class. can someone explain how are we able to create the object of B outside class B??
Because a Top Level Class is a happy family, everyone can access one another despite private.
JLS 6.6.1
6.6.1. Determining Accessibility
A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
You're allowed to even access private variables of that class too (try it!).
This is because you are defining that class inside the same class your calling it from, so you have private/internal knowledge of that class.
If you move Class B outside of Class A, it will work as expected.
Refer the JLS 6.6.1:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
The way this is implemented is using synthetic package-protected methods.
"If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Refer to this code:"
class ABC{
private interface MyInterface{
public void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
You said that
A class having private constructor means we can create object inside the class only
But
Thats happened because you define your inner Class in main(String[] args) method Not in Top Level Class
If you try that
public class A {
class B {
private B() {
System.out.println("local");
}
}
public static void main(String[] args) {
B b1 = new B(); // you cant create object of inner Class B
System.out.println("main");
}
}
Then you cant create object of inner Class B
public class InnerClass {
class Inner
{
public void method()
{
System.out.println("Innerclass");
}
}
}
class Sample extends InnerClass.Inner
{
public static void main(String [] arg)
{
Sample s = new Sample(new InnerClass());
s.method();
}
//why is this mandatory???
Sample(InnerClass i) {
i.super();
}
#Override
public void method() {
System.out.println("derived class");
}
}
when i make a class that derives from an innerclass (Innerclass.Inner) default constructor doesn't works. later i came to know that it requires to include a constructor taking Enclosing class reference why is it so?
Non static inner classes in Java have an implicit reference to the enclosing instance. You can solve your problem with:
public class InnerClass {
static class Inner // can make it public too
{
public void method()
{
System.out.println("Innerclass");
}
}
}
Just don't expect to be able to call any methods on InnerClass without a specific instance.
Because non-static inner classes have an implicit member that points back to their outer class, and you can't create an instance of the inner class without giving it that pointer. If you directly create an instance of an inner class, you have to use new outer.Inner() (or it might be outer.new Inner(), I can never remember). But Sample isn't an inner class, it just inherits one, so the outer instance must be passed in its constructor to the base constructor. Thus, it needs to have some instance of outer available, or create it itself.
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).