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();
Related
Is there something equivalent for StaticClass::new for inner class given the outer class instance?
Edit:
I.e. if I have
class Outer {
class Inner {
}
}
I can do Outer o = new Outer(); Inner i = o.new Inner() in old Java. How can I express the o.new Inner() as function reference.
According to the Oracle tutorials, there are four kinds of method references:
Reference to a static method
ContainingClass::staticMethodName
Reference to an instance method of a particular object
containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
Reference to a constructor
ClassName::new
References to a local/nested class are not listed, so I would assume it's not supported.
You can use the java.util.function.Supplier to trigger the usage of lambdas in order to obtain an instance of the nested class:
Outer outer = new Outer();
Supplier<Outer.Inner> supplier = () -> outer.new Inner();
The Chapter 15.13. Method Reference Expressions in the JLS contains a somewhat cryptic statement about this:
The immediately enclosing instance of a new inner class instance (§15.9.2) is provided by a lexically enclosing instance of this (§8.1.3).
This basically means that a method reference to the constructor of an inner class is possible in a method of the outer class, like in this example
import java.util.function.Supplier;
class Outer
{
public class Inner
{
}
void example()
{
Supplier<Inner> s = Inner::new;
}
}
But the JLS does not mention any alternative, so one has to assume that it is simply not possible to provide the enclosing instance in any other form than being this.
For static nested class, you can refer to it using outer class - OuterClass.NestedClass::new:
public class Main {
public static void main(String[] args) {
int[] array = {1, 2, 3};
Arrays.stream(array).forEach(A.B::new);
}
}
class A {
public A(int x) {
System.out.println("A created, x = " + x);
}
public static class B {
public B(int x) {
System.out.println("B created, x = " + x);
}
}
}
For inner class (nested non-static class), you can do outerInstanceName.new InnerClass(...):
public class Main {
public static void main(String[] args) {
int[] array = {1, 2, 3};
A a = new A(500);
Arrays.stream(array).forEach(x -> a.new B(x));
}
}
public class A {
public A(int x) {
System.out.println("A created, x = " + x);
}
public class B {
public B(int x) {
System.out.println("B created, x = " + x);
}
}
}
My IDE suggests me to convert x -> a.new B(x) into A.B::new, but this doesn't compile, because B is not static - it belongs not to the class A but to the instance of class A. So answering your question - I think it is not possible and you will have to use outerInstanceName.new InnerClass(...).
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.
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.
If I have an inner class e.g.
class Outer{
class Inner{}
}
Is there any way to check if an arbitrary Object is an instance of any Inner, regardless of its outer object? instanceof gives false when the objects are not Inners from the same Outer. I know a workaround is just to make Inner a static class, but I'm wondering if what I'm asking is possible.
Example:
class Outer{
Inner inner = new Inner();
class Inner{}
public boolean isInner(Object o){
return o instanceof Inner;
}
}
Outer outer1 = new Outer();
Outer outer2 = new Outer();
boolean answer = outer1.isInner(outer2.inner); //gives false
And what about?
public static boolean isInnerClass(Class<?> clazz) {
return clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers());
}
The method isMemberClass() will test if the method is a member (and not an anonymous or local class) and the second condition will verify that your member class is not static.
By the way, the documentation explains the differences between local, anonymous and nested classes.
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.
o instanceof Outer.Inner gives false when o is an instance of an Inner of any Outer other than the one you're calling it from.
This doesn't happen for me - I get true for o instanceof Inner regardless of which particular enclosing instance of Outer the o belongs to:
class Outer {
class Inner {}
void test() {
// Inner instance that belongs to this Outer
Inner thisInner = new Inner();
// Inner instance that belongs to a different Outer
Outer other = new Outer();
Inner otherInner = other.new Inner();
// both print true
System.out.println(thisInner instanceof Inner);
System.out.println(otherInner instanceof Inner);
}
public static void main(String[] args) {
new Outer().test();
}
}
Tested with both Java 6 and 7.
Did you try using getEnclosingClass():
Returns the immediately enclosing class of the underlying class. If the underlying class is a top level class this method returns null.
Outer.class.equals(object.getClass().getEnclosingClass())
Getting the correct enclosing class of the object , IMHO is not so easy . Read this.
Somewhat of a hack would be :
object.getClass().getName().contains("Outer$");
you could always:
getClass().getName()
and do a String comparison.
EDIT : to account for inheritance (among inner classes? who would do that?!) you could always loop through getSuperclass() and check for them as well, and even go after implemented interfaces.
The java.lang.Class.getEnclosingClass() method returns the immediately enclosing class of the underlying class. If this class is a top level class this method returns null.
The following example shows the usage of java.lang.Class.getEnclosingClass() method:
import java.lang.*;
public class ClassDemo {
// constructor
public ClassDemo() {
// class Outer as inner class for class ClassDemo
class Outer {
public void show() {
// inner class of Class Outer
class Inner {
public void show() {
System.out.print(getClass().getName() + " inner in...");
System.out.println(getClass().getEnclosingClass());
}
}
System.out.print(getClass().getName() + " inner in...");
System.out.println(getClass().getEnclosingClass());
// inner class show() function
Inner i = new Inner();
i.show();
}
}
// outer class show() function
Outer o = new Outer();
o.show();
}
public static void main(String[] args) {
ClassDemo cls = new ClassDemo();
}
}
Output
ClassDemo$1Outer inner in...class ClassDemo
ClassDemo$1Outer$1Inner inner in...class ClassDemo$1Outer
I was googling for finding out better answers, to find out that there are none out there.
Here is what I have which works pretty well:
public static boolean isStatic(Class klass) {
return Modifier.isStatic(klass.getModifiers());
}
/**
* Non static inner class
*/
public static boolean isInnerclass(Class klass) {
return klass.getDeclaringClass() != null && !isStatic(klass);
}
Will return true for local inner classes. isMemberClass and others do not work for this purpose.
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