Trouble instantiating inner class - java

I'm learning how to use inner classes, but I'm encountering a troubling error when I try to compile it. I'm trying to see how inner and outer classes can use one another's variables and methods.
When I try to compile this code it says:
.../src/MyOuter.java:39: non-static variable inner cannot
be referenced from a static context
Code:
public class MyOuter{
private int x;
public MyInner inner = new MyInner();
public int getOuterX(){
return x;
}
private void doStuff(){
inner.go();
}
class MyInner{
public int getInnerX(){
return x;
}
void go(){
x = 42;
}
}
public static void main(String[] args) {
MyOuter outer = new MyOuter();
outer.doStuff();
System.out.println("outer.x = " + outer.getOuterX());
System.out.println("inner.x = " + inner.getInnerX());
}
}
Thanks in advance for the help!

Since getInnerX() method is defined in MyInner class. You can't access it directly without the object of MyInner class .So change the line
System.out.println("inner.x = " + inner.getInnerX());
to
System.out.println("inner.x = " + outer.inner.getInnerX());

As was said, you first need to extract the inner variable before referencing it the static main method. Try something like the following:
{
public static void main(String[] args) {
MyOuter outer = new MyOuter();
MyInner inner = outer.inner;
outer.doStuff();
System.out.println("outer.x = " + outer.getOuterX());
System.out.println("inner.x = " + inner.getInnerX());
}
From Understanding Instance and Class Members:
Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
Since your inner variable is associated with an object, it cannot be referenced like a static variable might be. Were it static, it would be shared between all instance of 'MyOuter' and would be accessible in the manner you have tried there.

Related

Java Inheritance issue with static and non-static context

Please help me I am facing bit problem in Java code.
I am not able to understand how to fix the error.
Please help.
public class A {
private int a = 100;
public void setA(int value) {
a = value;
}
public int getA() {
return a;
}
}
public class B extends A {
private int a = 222;
public static void main(String[] args) {
System.out.println("in main(): ");
a = 123;
System.out.println("a = "+super.a );
}
}
The error I get is:
int a in class Main must be static
First of all, you should tell us the error :).
It looks like you are trying to access a variable in a non-static context from a static context (main method is static).
You should do something like below:
public class B extends A {
public static void main(String[] args) {
B b = new B();
b.setA(123)
System.out.println("a = " + b.getA());
}
}
It doesn't make sense to declare another 'a' variable in the child class. If you want to access 'a' directly, you can declare the field in class A as protected.
First of all, just to be clear prior to going to the code, your 2 classes, given they are both public, must be in their own separate files.
Now let's go to your code. The error lies first in this statements inside your main method:
a = 123;
You are accessing B's instance variable a from a static context -this is one.
Second:
System.out.println("a = "+super.a );
A's instance variable a is never inherited by B because it has a private access modifier.
If you want to access A's a, you could create an instance of A, and use that to call the getA() method which returns the value of A's a
Cheers,

Accessing static member by static object

Its said that, statics are much comfortable with statics in java. I'm trying to achieve small thing there where I want to change outer's class static variable value using inner static class's instance for that specific instance only. I think its a ideal case. If not please share with me. And moreover all inner classes have access to outer class's members.
So here is my code.
package org;
import org.Outerclass.innerclass;
public class Outerclass {
static String name = "Europe";
String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
void setstaticname() {
Outerclass.innerclass i = new Outerclass.innerclass();
i.name = "London"; // Error "name cannot be resolved or is not a field" ?
System.out.println(i.name);
}
static class innerclass {
void updatename() {
Outerclass o = new Outerclass();
o.setname("USA");
}
}
public static void main(String[] args) {
innerclass p = new innerclass();
System.out.println(p.name); // Error "name cannot be resolved or is not a field" ?
}
}
I have tried in two ways and vice versa but same errors. Any suggestions ?
name is a member of OuterClass. And you are trying to access it using innerclass instance. That's why you are getting this error.
Also what is this + here System.out.println(+p.name); ?
Edit:
From inner class you can access outer class static members just like below:
name = "";
or
Outerclass.name = "";
change +p.name to name or OuterClass.name. + inside System.out.println will give you another compile time error.
static members are not available in object level they are available in class level. static are initialized at compile time where object is created at run time
i.name should be Outerclass.name since name is a member of Outerclass and not innerclass
in your code, i is an instance of innerclass.

call inner class inside static method in same class in java [duplicate]

I working on a sample problem of over-ridding hashCode and equals method but getting an error: "No enclosing instance of type CustomHashCodeExample is accessible. Must qualify the allocation with an enclosing instance of type CustomHashCodeExample (e.g. x.new A() where x is an instance of CustomHashCodeExample)."
I wrote an inner class HashPerson and I am getting this error when I am trying to instantiate this inner class in another method called testHashCodeOverride().
public static void testHashCodeOverride(){
System.out.println("\nTest HashCode Override Method");
System.out.println("==================================\n");
HashPerson william = new HashPerson("willy");
HashPerson bill = new HashPerson("willy");
}
This code works fine, even though I dont see static inner class or instantiation of outer class, confused :(
public class HashCodeExample {
public static void testHashCodeOverride() {
HashPerson william = new HashPerson("Willy");
HashPerson bill = new HashPerson("Willy");
System.out.println("Hash code for william = " + william.hashCode());
System.out.println("Hash code for bill = " + bill.hashCode());
HashMap table = new HashMap();
table.put(william, "Silly");
if (table.containsKey(william)) {
System.out.println(table.get(william));
} else {
System.out.println("Key " + william + " not found");
}
if (table.containsKey(bill)) {
System.out.println(table.get(bill));
} else {
System.out.println("Key " + bill + " not found");
}
}
class HashPerson {
private static final int HASH_PRIME = 1000003;
public HashPerson(String name) {
this.name = name;
}
public String toString() {
return name;
}
public boolean equals(Object rhs) {
if (this == rhs)
return true;
// make sure they are the same class
if (rhs == null || rhs.getClass() != getClass())
return false;
// ok, they are the same class. Cast rhs to HashPerson
HashPerson other = (HashPerson) rhs;
// our test for equality simply checks the name field
if (!name.equals(other.name)) {
return false;
}
// if we get this far, they are equal
return true;
}
public int hashCode() {
int result = 0;
result = HASH_PRIME * result + name.hashCode();
return result;
}
private String name;
}
}
I think you want to declare the HashPerson class as static. Otherwise it can only be instantiated in the context of the containing class, either in a method of the containing class or using code like this:
ContainingClass container = new ContainingClass();
HashPerson william = container.new HashPerson("willy");
Actually, my rule-of-thumb is to make any nested class static, unless I have a special reason not to. This is also more efficient, because non-static nested classes (called inner classes) always contain an implicit reference to the containing object.
You need to either make your inner class static, or refer to it through an instance of the outer class. Most likely you just want to make your inner class static.
Non-static members of a class (variables, methods, inner classes) are per instance of the class. Therefore, when accessing non-static members from a static context (such as a static method like testHashCodeOverride), you need to specify an instance of the enclosing class.
As i can see there could be different possible ways to instantiate the Inner Classes
Static Inner Class : When Inner class is static, let say code looks like as describe.
class OuterClass
{
static int outer_x = 10;
int outer_y = 20;
// static nested class
static class StaticNestedClass {
void display() {
}
}
}
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
or Just this could be sufficient for static classes
new StaticNestedClass();
Local inner Classes (Non Static) : Inner Classes which are not static, one good thing with local inner classes that they can access all private data members of enclosed class.
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Anonymous Inner Class (implementing Interface) : This type of classes generally hidden, One can't directly see the Class{...} block in code , That is why known as Anonymous Inner Class. Here describes how to instantiate it in case inner class implementing an interface Runnable Interface.
Runnable r = new Runnable()
{
//This is Anonymous Class
public void run() {
System.out.println("Child Thread");
}
};
Anonymous Inner Class (Extending One Class):We can have an anonymous inner class that extends a class, Here i am taking example of Thread Class,
Thread t = new Thread(new Runnable()
{
//Anonymous Inner class
public void run() {
System.out.println("Child Thread");
}
});
Anonymous Inner class that defines inside method/constructor argument : Inner Classes could be define within methods as well, here giving example how can we define and instantiate it within argument
public static void main(String[] args)
{
//Here we are using Anonymous Inner class
//that define inside argument, here constructor argument
Thread t = new Thread(new Runnable()
{
public void run()
{
System.out.println("Child Thread");
}
});
t.start();

Inner Class change external variable java

I use Vaadin for my project and I have a question: How change variable external class franchSize?
TextField franchSize = new TextField();
franchSize.setDebugId("franch_size");
hl1.addComponent(franchSize);
franchSize.setValue("0");
hl1.setComponentAlignment(franchSize,
Alignment.MIDDLE_CENTER);
franchSize.addListener(new Property.ValueChangeListener() {
private static final long defaultValue = 0;
public void valueChange(ValueChangeEvent event) {
String value = (String) event.getProperty().getValue();
if(Integer.valueOf(value)%1==0){
franchSize.setValue("0");
franchSize.getWindow().showNotification("","Bla-bla-bla",Notification.TYPE_HUMANIZED_MESSAGE);
}
}
});
Error: "Cannot refer to a non-final variable franchSize inside an inner class defined in a different method" in "franchSize.setValue("0");" and "franchSize.getWindow().showNotification("","Bla-bla-bla",Notification.TYPE_HUMANIZED_MESSAGE);"
Here is a simple implementation for communicating with outer class variable,
public class Google01 implements Outer{
// outer class variable, see no final here
int outer = 0;
public static void main(String[] args) {
Google01 inst = new Google01();
inst.testMe();
}
public void testMe(){
// Inner class
class temp{
Outer out;
public temp(Outer out) {
this.out = out;
}
public void printMe(String text){
// reading outer variable
System.out.println(out.getValue() + text);
// setting outer variable
out.setValue(out.getValue() + 1);
}
}
// Lets start our test
temp obj = new temp(this);
System.out.println("Value of outer before call = " + outer);
// this should increment outer value, see number before Yahoo in output
obj.printMe("Yahooo");
obj.printMe("Google");
obj.printMe("Bing");
// Lets print outer value directly.
System.out.println("Value of outer after call = " + outer);
}
#Override
public void setValue(int value) {
outer = value;
}
#Override
public int getValue() {
return outer;
}
}
// An interface that is use to communicate with outer class variable.
interface Outer{
void setValue(int value);
int getValue();
}
Output
Value of outer before call = 0
0Yahooo
1Google
2Bing
Value of outer after call = 3
Brief Explaination:
You need to make an interface in order to talk to outer class ( I like making interface for communication but it can be done using passing outer class instance also instead of making whole new interface), and you can use the utility method provided by interface in order to get or put the value in outer class.
You can refer this to know why your error occur.
Only thing that i have changed in the scenario is that i have made the variable as class level variable (member variable) from method variable.
The error is pretty clear here: you cannot access a external variable inside an inner class without making it final. So just add final in front of TextField franchSize = new TextField();
make franchSize final -- as stated in the error message -- or use (TextField)event.getSource() instead of referencing the outer variable.
for informations about the error search SO
Just create a (private) field 'TextField franchSize' in the outer class.
Best way to access it then, is to use a protected getter.

Can a Static Nested Class be Instantiated Multiple Times?

Given what I know of every other type of static feature of programming––I would think the answer is 'no'. However, seeing statements like OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass(); makes me wonder.
Yes, there is nothing in the semantics of a static nested type that would stop you from doing that. This snippet runs fine.
public class MultipleNested {
static class Nested {
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Nested();
}
}
}
See also
public static interface Map.Entry<K,V>
public static class AbstractMap.SimpleEntry<K,V>
Probably the most well-known nested type. Obviously instantiated multiple times.
Now, of course the nested type can do its own instance control (e.g. private constructors, singleton pattern, etc) but that has nothing to do with the fact that it's a nested type. Also, if the nested type is a static enum, of course you can't instantiate it at all.
But in general, yes, a static nested type can be instantiated multiple times.
Note that technically, a static nested type is not an "inner" type.
JLS 8.1.3 Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly declared static.
That is, according to JLS terminology, an inner class is one that isn't static. If it's static, then it's just a nested type.
So what does static mean?
static simply means that the nested type does not need an instance of the enclosing type to be instantiated.
See also
Java inner class and static nested class
Java: Static vs non static inner class
#polygenelubricants :
But in general, yes, a static nested
type can be instantiated multiple
times.
Just to be sure 100% of that I extended your snippet:
public class MultipleInner {
static class Inner {
private int state;
public int getState() { return state; }
public void setState(int state) { this.state = state; }
}
public static void main(String[] args) {
List<Inner> inners = new ArrayList<Inner>();
for (int i = 0; i < 100; i++) {
Inner inner = new Inner();
inner.setState(i);
inners.add(inner);
}
for (Inner inner : inners) {
System.out.println(inner.getState());
}
}
}
And of course the result is:
0
1
2
3
.
.
.
97
98
99
It is legal. The fact that the inner class is static gives you a benefit here; its instances are not bound to any instance of the containing class, so they can be freely instantiated (as long as the access qualifier allows it).
The price, however, is that the inner class can't use non static members/methods of the containing class.
Yeah you can make instances of it as many times as you want.
Maybe the reason why you see that, is because the programme thought about storing a reference somewhere. Though i agree with you seems strange :S
Inner class can use non static members/methods of containing class. It can use them only through an object reference of the enclosing class-
public class MultipleInner {
private int outerstate =10;
static class Inner {
private int state;
public int getState() { return state; }
public void setState(int state) { this.state = state; }
}
public static void main(String[] args) {
Inner inner = new Inner();
inner.setState(new MultipleInner().outerstate);
System.out.println(inner.getState());
}
}
So, inner class doesn't have to pay the price of not being able to access the non static members of the enclosing class.
Static nested classes are indeed instanced - they are, as said, top-level classes which live in the namespace of the 'outer' class, and obey static semantics respecting references to the 'outer' class. This code sample demonstrates :
public class OuterClass {
String outerStr = "this is the outer class!!" ;
public static class StaticNestedClass {
String innerStr = "default / first instance" ;
}
public static void main(String[] args) {
OuterClass.StaticNestedClass nestedObject1 = new OuterClass.StaticNestedClass();
OuterClass.StaticNestedClass nestedObject2 = new OuterClass.StaticNestedClass();
nestedObject2.innerStr = "second instance" ;
System.out.println(nestedObject1.innerStr) ;
System.out.println(nestedObject2.innerStr) ;
}
}
output:
default / first instance
second instance

Categories