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.
Related
inner class uses outer local variable is through its constructor like this InnerClass(String outerVar)
inner class uses outer field is through this.
I read it from an article that programmers who use Java are not used to to having variable changed both sides, otherwise it causes a AAD (Action At remote Distance).
If that is true, outer field can be changed both sides causes the same AAD problem.
What are the thinkings behind local var is final while field is not.
void test() {
var a = "a"; // outer local variable
class InnerClass {
void print() {sout(a);} // InnerClass(String a)
}
}
String a = "a" // outer field
void test() {
class InnerClass {
void print() { a = newA;} // OuterClass.this.a = newA
}
sout(a) // newA
}
Local variables are allocated on the stack and invalidated as soon as the method ends while fields are allocated on the heap.
If the inner class tried to access a local variable after the method ended, it would access invalid memory (possibly overwritten by something else). As fields are allocated on the heap, this is no problem because those are not invalidated until there is no reference to the object.
If the variable is final, the inner class can just access a copy as the copy will always be the same as the original variable (cannot be changed).
Using a copy with non-(effectively) final variables would cause logical errors if you would modify the variable later in the method as the copy wouldn't catch up (or the original value wouldn't ve updated if the copy us changed).
Objects are allocated on the heap, meaning those are shared between methods and threads. Objects and their instance variables exist as long as there is a reference to them.
However, not that caution should be taken when working with multiple threads as you may encounter synchronisation and visibility issues (not the topic of this question, though).
An inner class has a hidden unnamed field referencing the outer class. For the sake of this answer, we'll name it $outer.
The first version:
public class OuterClass {
void test() {
var a = "a"; // Local variable
class InnerClass {
void print() { sout(a); } // sout("a")
}
new InnerClass().print();
}
}
That actually gets compiled to:
public class OuterClass {
void test() {
final String a = "a";
new OuterClass$0$InnerClass(this, a).print();
}
}
final class OuterClass$0$InnerClass {
private final OuterClass $outer;
private final String a;
OuterClass$0$InnerClass(OuterClass $outer, String a) {
this.$outer = $outer;
this.a = a;
}
void print() { sout(this.a); } // sout("a")
}
As you can see, the local variable gets copied. The enforcement of final is to prevent the confusion that would occur if the local variable were changed after the value was copied.
The second version:
public class OuterClass {
String a = "a"; // Outer field
void test() {
class InnerClass {
void setA(String newA) { a = newA; }
}
new InnerClass().setA("b");
sout(a); // sout("b")
}
}
Which gets compiled to:
public class OuterClass {
String a = "a"; // Outer field
void test() {
new OuterClass$0$InnerClass(this).setA("b");
sout(a); // sout("b")
}
}
class OuterClass$0$InnerClass {
private final OuterClass $outer;
OuterClass$0$InnerClass(OuterClass $outer) {
this.$outer = $outer;
}
void setA(String newA) { this.$outer.a = newA; }
}
Since the value of field a is not copied, there is no need to enforce final behavior.
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,
I came across this kind of example and had difficulty to understand it's actuall purpose:
class YieldDemo extends Thread
{
static boolean finished = false;
static int sum = 0;
public static void main (String [] args)
{
new YieldDemo ().start ();
for (int i = 1; i <= 50000; i++)
{
sum++;
if (args.length == 0)
Thread.yield ();
}
finished = true;
}
public void run ()
{
while (!finished)
System.out.println ("sum = " + sum);
}
}
I've never seen this kind of implementation - why initiating a the new class inside the same class object and not outside the class? is there any particular reason?
In fact you are outside of the class object itself. The main method is a static method, thus it has no dependency on any object instance.
You could also move the main method to any other java file. In general it will also work. However, you need to put static methods in some file. As every java file needs to be a class, you may put the method in the class it works for. For example, the class Math in java is a pure utility class, it has no non-static method.
However, if you create something like this:
public final class Value {
private final int mValue;
public Value(int value) {
mValue = value;
}
public int getValue() {
return mValue;
}
public Value increase() {
return new Value(mValue + 1);
}
}
It can actually make sense if you want Value to be immutable (not change its internal value). So, calling increase() does not increase the value itself but creates a new instance of this object, with an increased value.
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();
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.