I want to create an instance of class B that isn't a part of A's inner class.
How can I achieve this? I'd like the class name to remain the same for both B classes.
public class Sample {
public static void main(String[] args) {
A a = new A();
a.show();
}
}
class A {
class B {
public void show() {
System.out.println("hello");
}
}
public void show() {
B b = new B();
b.show();
}
}
class B {
public void show() {
System.out.println("hellohello");
}
}
Use full qualified name of class B, i.e. com.mypackage.mysubpackage.B for outer B and com.mypackage.mysubpackage.A.B for inner B.
You can use the fully-qualified name of B to always refer to it: packageName.B.
This won't work if the class is in the unnamed (default) package (i.e. if there is no package declaration on top of its .java file). This is yet another reason not to use the unnamed package at all (i.e. all your classes should be in a named package).
Use the complete identifier of the class you want to create an instance of (no import statement).
yourPackage.B variable = new yourPackage.B();
Replace your main method with the code below:
public static void main(String[] args) {
A a = new A();
a.show();
//For Outer Class
B bOuter =new B();
bOuter.show();
//For Inner Class
A.B bInner=new A().new B();
bInner.show();
}
Use complete qualified name to keep away from conflict among same classes name.
E.g. packageName.A.B and packageName.B
Related
If I have a class A and its subclass B.
package washington;
public class A{
protected A(){}
}
package washington;
public class B extends A{
public B(){super();} // it works
public static void main (String[] args){
A b = new A(); // it does work.
}
}
The class A has a protected constructor, but I cannot access the constructor in B. I think it is a rule, however, I cannot find a webpage describing this situation.. All that I saw mention protected can be accessed from subclass, same-package.... e.t.c.
package california;
public class A extends washington.A{
public static void main (String[] args){
new washington.A(); // it does not work.
}
}
I wonder if this is because I use IntelliJ IDEA 2017.3.4.. compiler is javac 9.0.4
It seems that the problem is that you have your classes in different packages. Java doc says:
If the access is by a simple class instance creation expression new C(...), or a qualified class instance creation expression E.new C(...), where E is a Primary expression, or a method reference expression C :: new, where C is a ClassType, then the access is not permitted. A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) or a method reference expression only from within the package in which it is defined.
class A{
protected A() {
System.out.println("hello from A");
}
}
class B extends A{
public B() {
super();
System.out.println("hello from B");
}
public static void main (String[] args){
A b1 = new B(); // you can either do this
B b2 = new B(); // or this
}
}
Try running the program and you will see the expected result printed on console.
I was randomly writing a code & encountered a problem: how to instantiate class E (shown below) which is defined within an anonymous inner class; like:
A c = new A() {
class E{ //Statements
}
};
You can't write a program that uses an ordinary call to new to do that: in order for a class to be instantiated, it must have a name. Anonymous inner classes, as that term implies, do not have a name.
Thus a class that exists within that anonymous inner class also has no name; thus it can not be instantiated outside of that anonymous inner class.
But you can use reflection. See my Test.java:
import java.util.*;
import java.lang.reflect.*;
class B {
B() { System.out.println("B"); }
void foo() { System.out.println("B.foo"); }
}
public class Test{
B b;
void bar() {
b = new B() {
class C { C() { System.out.println("inner C"); } }
void foo() { System.out.println("inner foo"); }
};
b.foo();
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.bar();
Class<?> enclosingClass = Class.forName("Test$1");
Class<?> innerClass = Class.forName("Test$1$C");
Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass);
Object innerInstance = ctor.newInstance(test.b);
}
}
This prints:
B
inner foo
inner C
So, yes, given the fact that we can use the mangled class name Test$1$C at runtime, and that reflection allows us to instantiate objects at runtime, too (see here for details), the final answer is: yes, it is
possible.
But just for the record: that doesn't mean at all that one should ever do something like this in real code. This is a nice little puzzle to train creativity; but not suited for anything in the real world.
In the real world, an inner class within an anonymous inner class is a design bug. End of story.
public class B {
public static void main(String[] args) {
A a = new A();
}
}
public class A {
A b = new A();
}
Because every A creates an inner field named b of type A. That's infinitely recurisve, because to create a b you must also create an A (which adds another b). Because initializers are copied to the default constructor, your example is equivalent to something like,
public class A {
// A b=new A();
A b;
public A() {
super();
b = new A();
}
}
I dont understand your requirement. Why did you declare instance variable within same class. It will behave like a recursive loop. From the main method it will try to create the object of class A and during that object creation it will try to initialize the variable "a". As a result again it will create another instance of A and so on.
I have a program with multiple classes, and when I try to make an instance of one of these objects in main, I get an error. How do I properly create a class in main with multiple classes?
public class A {
class B {
}
class C {
}
public static void main(String[] args) {
B b = new B();
C c = new C();
}
Error: No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A
This is because B and C are inner classes. Unless you understand inner classes, this is probably not what you want.
Move them outside A:
public class A {
public static void main(String[] args) {
B b = new B();
C b = new C();
}
}
class B {
}
class C {
}
I am try to find out why below code is giving error, Can anybody explain please.
Here is a class
package abc;
public class A {
public class B {
}
}
Now I am try to create a B class
package xyz;
import abc.*;
public class B extends A{
public static void main(String[] args) {
B b = new B (); // this line gives error. Can you please explain
}
}
Please consider class B extends A is in default package means
import abc.*;
public class B extends A{
public static void main(String[] args) {
B b = new B (); // this line gives error. Can you please explain
// I am try to create "B" class object which extends A
//.. not the B inner class
}
}
Error shows in eclipse is : "No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A (e.g. x.new A() where x is an instance of A)."
Given that B extends A, and A contains an inner class B, I suspect there's room for confusion (for both compiler and programmer).
The line:
B b = new B();
is ambiguous. Which B is this ? As pointed out elsewhere, the inner class B needs an containing instance of A, so I suspect you mean the B outer class.
Edit: Your error
"No enclosing instance of type A is accessible. Must qualify the
allocation with an enclosing instance of type A (e.g. x.new A() where
x is an instance of A)."
confirms this. I presume you want the xyz.B and should scope that appropriately.
Try to specify the enclosing scope:
B b = new A.B();
or
B b = new xyz.B();
If you make public class B static, it will work as written.
Otherwise, you cannot make instances of class B from outside an instance of class A, because non-static inner classes require a pointer to their outer class's "this" (within a B, you can write this.A, and that will actually refer to the enclosing A).
When I create the following in Eclipse:
package com.example;
public class A {
class B {
}
}
and
package com.example;
import com.example.A.B;
public class B extends A {
public static void main(String[] args) {
B b = new B();
}
}
As you can see Eclipse imports the class A.B . Without the import the following error is noted:
No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A (e.g. x.new A() where x is an instance of A).
The error I get when I try to compile this code (minus the package specs since they seem irrelevant) is "non-static variable this cannot be referenced from a static context". So, the problem is that within the static method main() you are trying to access something non-static, which I guess is the definition of the inner class B.
You actually get the same error if the second outer class has a different name. So the apparent naming conflict is a red herring. Although that itself is a good reason not to use the same name for both classes -- it causes confusion when trying to understand the error.
If I change the declaration of the inner class to be static, the error is resolved.
public class A {
public static class B {
}
}
Some relevant discussion of static vs. non-static nested classes is here.
But this may not be the correct fix. It shows that your code in main() is referencing the B inner class, not the B class that contains the method. Which did you actually want? Obviously, I'd suggest using different names for this two classes to avoid confusion. If what you want in main() is to create an instance of the class that contains that method, then using a unique name for that class will solve your problem.
Your class B extends A has inherited the class A.B and the expression new B() refers to that inner class. Therefore it asks for an enclosing instance. You must either explicitly qualify both your mentions of B with the package name, or, far better, avoid such naming mess in the first place.
I found this solution, through reflection you can create B class(B extends A class) object.
import java.lang.reflect.Method;
import abc.*;
public class B extends A{
public static void main(String[] args) {
//B b = new B(); // this line gives error. Can you please explain
// I am try to create "B" class object which extends A
//.. not the B inner class
try{
Class c = Class.forName("B"); //class B extends A
Method m=c.getMethod("print", null);
m.invoke(c.newInstance(), null);
}catch(Exception e){
e.printStackTrace();
}
}
public void print(){
System.out.println("Printed");
}
}