Surprising access to fields with Java anonymous class - java

I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.
I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
public interface AnonInt {
void print();
}
public class AnonTest {
private int a;
public AnonTest(int a) {
this.a = a;
}
public AnonInt foo() {
return new AnonInt() {
public void print() {
System.out.println(a);
}
};
}
public static void main(String[] args) {
AnonTest at = new AnonTest(37);
AnonInt ai = at.foo();
ai.print();
}
}

Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
Since the reference to a is unambiguous in your context, the two expressions reference the same field.
Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.

Related

Can Anonymous inner class instantiated within a static method has access to instance members of containing class?

I want to understand better the visibility of instance fields of containing class to an Anonymous inner class (AIC).
There have been lots of talks that AIC has an implicit reference to the containing class' instance (When exactly is it leak safe to use (anonymous) inner classes?). With that logic, even when an AIC is instantiated within a static method, it should have access to the instance fields of the containing class. But I can't find a way to test this as the compiler gives errors.
For e.g., in the below code, I get: "Non-static field 's' can't be referred from a static context" by the compiler when I refer 's' within print() method of the AIC:
public interface TestInterface {
void print();
}
public class AICTest {
public String s = "something";
public static void main( String[] args ) {
new TestInterface() {
#Override
public void print() {
System.out.println( s ); **<-- compilation error**
}
}.print();
}
}
Could you suggest if it's possible for the AIC instance to access 's' in the above example?
Edit/Answer
I want to clarify that I am aware that static methods have access to class members and instance methods have access to instance & class members. The confusion was more about the general statement that AIC always have an implicit reference to containing class' object. This clearly is not the case for AIC initialised within a static method. #shmosel shared a link which answers my question (Is it possible to make anonymous inner classes in Java static?): "So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.".
You have to have an instance of AICTest to read 's' out of, since 's' is an instance variable. Here's an example that will work, representing your example modified to access an existing AICTest object that could potentially come from anywhere:
class AICTest {
public String s = "something";
public static void main( String[] args ) {
AICTest aic = new AICTest();
new TestInterface() {
#Override
public void print() {
System.out.println(aic.s);
}
}.print();
}
}
To be clear, running 'main' does not create an instance of AICTest. You have to do a 'new' somewhere to create an instance of AICTest.
Another option is to make 's' static. Then it isn't associated with any particular AICTest object, and so it exists even if you haven't instantiated an AICTest object:
class AICTest {
public static String s = "something";
public static void main( String[] args ) {
new TestInterface() {
#Override
public void print() {
System.out.println(s);
}
}.print();
}
}
As you can see, I haven't added any visibility modifiers. So your idea about visibility was sound. If it otherwise makes sense to access 's', the visibility is there in your code. The problem here has nothing to do with visibility.
This may not be what you want, but you can:
interface TestInterface {
void print();
}
class AICTest {
public String s="something";
public static void main(String[] args) {
AICTest aicTest=new AICTest();
new TestInterface() {
#Override public void print() {
System.out.println(aicTest.s);
}
}.print();
}
}
The confusion was more about the general philosophy that AIC always have an implicit reference to containing class' object. This clearly is not the case for AIC initialised within a static method. #shmosel shared a link which answers my question (Is it possible to make anonymous inner classes in Java static?): "So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.".

What is the equivalent of :: operator in java?

When accessing a function from another class in c++,
we can write: classA::fct();
Is there an equivalent operator in java?
If not, how can we access a function from another class in java?
Well the ::-operator (Scope Resolution Operator) in C++ allows you to resolve ambiguous calls/references to identifiers. However, in java there are no independent functions as all functions are actually methods (members) of a class. As such there are no need for this operator, have a look here for differences between Java and C++ classes.
I am guessing you are attempting to access a member (possibly static) of a class, in which case you'd use the .-operator as exemplified in Mwesigye's answer or as follows:
public class AB {
public static void main(String[] args) {
B myB = new B();
myB.printA();
}
}
public class A {
public static int getInt() {
return 4;
}
}
public class B {
public void printA() {
System.out.println(A.getInt()); // output: 4
}
}
Here the .-operator is used to access printA() from the instantiated object myB (instantiated from class B). It is also used to access the static method getInt() whose implementation is tied to class A rather than any object of A. More info can be found here.
Take an example of a Class Student with methods what you call functions in c++
eg.
class Student{
//a non static method
public void getFees(){
//your logic
}
public static void deleteSubject(){
// your logic
}
}
class Club{
//create a new instance of student class
Student student = new Student();
public void printData(){
//access a non static method
student.getFees();
//accessing a static method
new Student().deleteSubject();
}
}
Hope this will help.

Android "new" statement not working. Loop keeps using the same object [duplicate]

This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Closed 6 years ago.
I have been told several definitions for it, looked on Wikipedia, but as a beginner to Java I'm still not sure what it means. Anybody fluent in Java?
static means that the variable or method marked as such is available at the class level. In other words, you don't need to create an instance of the class to access it.
public class Foo {
public static void doStuff(){
// does stuff
}
}
So, instead of creating an instance of Foo and then calling doStuff like this:
Foo f = new Foo();
f.doStuff();
You just call the method directly against the class, like so:
Foo.doStuff();
In very laymen terms the class is a mold and the object is the copy made with that mold. Static belong to the mold and can be accessed directly without making any copies, hence the example above
The static keyword can be used in several different ways in Java and in almost all cases it is a modifier which means the thing it is modifying is usable without an enclosing object instance.
Java is an object oriented language and by default most code that you write requires an instance of the object to be used.
public class SomeObject {
public int someField;
public void someMethod() { };
public Class SomeInnerClass { };
}
In order to use someField, someMethod, or SomeInnerClass I have to first create an instance of SomeObject.
public class SomeOtherObject {
public void doSomeStuff() {
SomeObject anInstance = new SomeObject();
anInstance.someField = 7;
anInstance.someMethod();
//Non-static inner classes are usually not created outside of the
//class instance so you don't normally see this syntax
SomeInnerClass blah = anInstance.new SomeInnerClass();
}
}
If I declare those things static then they do not require an enclosing instance.
public class SomeObjectWithStaticStuff {
public static int someField;
public static void someMethod() { };
public static Class SomeInnerClass { };
}
public class SomeOtherObject {
public void doSomeStuff() {
SomeObjectWithStaticStuff.someField = 7;
SomeObjectWithStaticStuff.someMethod();
SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass();
//Or you can also do this if your imports are correct
SomeInnerClass blah2 = new SomeInnerClass();
}
}
Declaring something static has several implications.
First, there can only ever one value of a static field throughout your entire application.
public class SomeOtherObject {
public void doSomeStuff() {
//Two objects, two different values
SomeObject instanceOne = new SomeObject();
SomeObject instanceTwo = new SomeObject();
instanceOne.someField = 7;
instanceTwo.someField = 10;
//Static object, only ever one value
SomeObjectWithStaticStuff.someField = 7;
SomeObjectWithStaticStuff.someField = 10; //Redefines the above set
}
}
The second issue is that static methods and inner classes cannot access fields in the enclosing object (since there isn't one).
public class SomeObjectWithStaticStuff {
private int nonStaticField;
private void nonStaticMethod() { };
public static void someStaticMethod() {
nonStaticField = 7; //Not allowed
this.nonStaticField = 7; //Not allowed, can never use *this* in static
nonStaticMethod(); //Not allowed
super.someSuperMethod(); //Not allowed, can never use *super* in static
}
public static class SomeStaticInnerClass {
public void doStuff() {
someStaticField = 7; //Not allowed
nonStaticMethod(); //Not allowed
someStaticMethod(); //This is ok
}
}
}
The static keyword can also be applied to inner interfaces, annotations, and enums.
public class SomeObject {
public static interface SomeInterface { };
public static #interface SomeAnnotation { };
public static enum SomeEnum { };
}
In all of these cases the keyword is redundant and has no effect. Interfaces, annotations, and enums are static by default because they never have a relationship to an inner class.
This just describes what they keyword does. It does not describe whether the use of the keyword is a bad idea or not. That can be covered in more detail in other questions such as Is using a lot of static methods a bad thing?
There are also a few less common uses of the keyword static. There are static imports which allow you to use static types (including interfaces, annotations, and enums not redundantly marked static) unqualified.
//SomeStaticThing.java
public class SomeStaticThing {
public static int StaticCounterOne = 0;
}
//SomeOtherStaticThing.java
public class SomeOtherStaticThing {
public static int StaticCounterTwo = 0;
}
//SomeOtherClass.java
import static some.package.SomeStaticThing.*;
import some.package.SomeOtherStaticThing.*;
public class SomeOtherClass {
public void doStuff() {
StaticCounterOne++; //Ok
StaticCounterTwo++; //Not ok
SomeOtherStaticThing.StaticCounterTwo++; //Ok
}
}
Lastly, there are static initializers which are blocks of code that are run when the class is first loaded (which is usually just before a class is instantiated for the first time in an application) and (like static methods) cannot access non-static fields or methods.
public class SomeObject {
private static int x;
static {
x = 7;
}
}
Another great example of when static attributes and operations are used when you want to apply the Singleton design pattern. In a nutshell, the Singleton design pattern ensures that one and only one object of a particular class is ever constructeed during the lifetime of your system. to ensure that only one object is ever constructed, typical implemenations of the Singleton pattern keep an internal static reference to the single allowed object instance, and access to that instance is controlled using a static operation
In addition to what #inkedmn has pointed out, a static member is at the class level. Therefore, the said member is loaded into memory by the JVM once for that class (when the class is loaded). That is, there aren't n instances of a static member loaded for n instances of the class to which it belongs.
Above points are correct and I want to add some more important points about Static keyword.
Internally what happening when you are using static keyword is it will store in permanent memory(that is in heap memory),we know that there are two types of memory they are stack memory(temporary memory) and heap memory(permanent memory),so if you are not using static key word then will store in temporary memory that is in stack memory(or you can call it as volatile memory).
so you will get a doubt that what is the use of this right???
example: static int a=10;(1 program)
just now I told if you use static keyword for variables or for method it will store in permanent memory right.
so I declared same variable with keyword static in other program with different value.
example: static int a=20;(2 program)
the variable 'a' is stored in heap memory by program 1.the same static variable 'a' is found in program 2 at that time it won`t create once again 'a' variable in heap memory instead of that it just replace value of a from 10 to 20.
In general it will create once again variable 'a' in stack memory(temporary memory) if you won`t declare 'a' as static variable.
overall i can say that,if we use static keyword
1.we can save memory
2.we can avoid duplicates
3.No need of creating object in-order to access static variable with the help of class name you can access it.

Confused about anonymous classes vs anonymous inner class

I went searching to learn how to do lambda expressions in Java, but instead a confusion came up for me. So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was. Lot of threads and videos I'm seeing seem to call anonymous inner classes just "anonymous classes." Are they synonymous? My understanding of anonymous inner class is:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
So essentially, instead of having to write a subclass for Square, and then override the calculatePerimeter() method, I can just make a one-time square class, and override the method in their. Is this correct?
So, anonymous inner classes have to do with inheritance. I'm not understanding the use of it though. Perhaps, it's because I've never used them before, or because I don't have much programming experience. Can you can give me examples or explain when it's useful?
UPDATE: When I moved my code for the anonymous inner class to an IDE, I learned that there are errors; So apparently, the "square" doesn't even inherit the fields of the rectangle. Doesn't this make it even more useless?
Would the equivalent be:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
}
public class Square extends Rectangle {
#Override
public void calculatePerimeter() {
perimeter = 4*getLength();
}
public double getLength() {
return length;
}
}
So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
There is no anonymous class there. The class SomeObject has a name ... therefore it is not anonymous. In fact, it is just a normal (non-nested, non-inner, non-anonymous) Java class.
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was.
There is no such thing as a "regular anonymous class". All Java anonymous classes are "inner".
As the JLS says:
"An inner class is a nested class that is not explicitly or implicitly declared static.
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5)."
So, anonymous inner classes have to do with inheritance.
Anonymous inner classes do involve inheritance, but that's not what makes them "inner". See above.
I meant the "list.add(I meant the "list.add(new SomeObject());". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.);". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.
You are incorrect. An object is not a class1.
The new SomeObject() is creating an object, not a class. But that's just normal. Objects / instances don't have names ... as far as the JLS is concerned.
Now variables and fields have names ... but variables are not objects / instances or classes. They are bindings between a name and a slot that can hold a reference to an object (if that's what the type declaration allows).
1 - except in the case of instances of java.lang.Class ... and even then the object is not actually the class / type from a theoretical standpoint.
Or is it called simply an anonymous object and I had two mixed up?
Nope. Objects don't have names. All Java objects are "anonymous". It is not a useful distinction to make. (And see above where I talk about variables ...)
As for your Rectangle / Square examples, they have nothing to do with anonymous classes, inner classes, nested classes or anything like that. They are just top-level classes, using ordinary Java inheritance. (Not that I'm suggesting there is another "non-ordinary" kind of inheritance ...)
First off - square can access fields in Rectangle. You need to mark them protected not private
public class Rectangle {
protected double length;
protected double width;
protected double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
Here are some good descriptions of Inner Classes, Anonymous and local
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html.
There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
Local classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
http://c2.com/cgi/wiki?AnonymousInnerClass
Anonymous Classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
I think the relevance of Anonymous classes comes when you are designing an API. You could create concrete classes to implement every bit of logic for every interface/abstract class but that would create tons of dependencies and you would still be missing some logic. A great example of anonymous classes is when using predicates for filtering. Like in Google Guava
Lets say I have a List<Integer> and I want to filter the numbers remove the 1s and return a new list
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1) rtn.push(i);
}
return rtn;
}
Now lets say I want to filter out 1 and 2
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1 && i != 2) rtn.push(i);
}
return rtn;
}
Now lets say 3 and 5s ... this logic is exactly the same except for the predicate check. So we will create an interface
interface FilterNumber {
public boolean test(Integer i);
}
class Filter1s implements FilterNumber {
public Filter1s(){};
public boolean test(Integer i) { return i != 1; }
}
public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(filterNumber.test(i)) rtn.push(i);
}
return rtn;
}
filter(list, new Filter1s());
As you can see with combinations this becomes tedious too. It would be easier to just allow the user of the api to define the logic they want to preform and if it is only needed once just use an anonymous class
filter(list, new FilterNumber() {
#Override
public boolean test(Integer i) {
return i != 1 && i != 3 && i != 7;
}
});
And extending to Lambdas, wouldn't it be even easier to take out all the bloat around i != 1
list.stream().filter( i -> i != 1 )
To answer a later comment, "when I write a new subclass, it inherits those private instance variables. In the case of the anonymous inner class, it didn't."
Subclasses never "inherit" private fields of the superclass (using the JLS terminology). However, subclasses may be able to refer to those private fields anyway, depending on where they're located. If the subclass is declared inside the superclass, or if they're both nested inside the same top-level class, the methods of the subclass can still access the field; assuming you have a source file C.java with just one class C, private fields declared somewhere in C.java are still accessible from most other places in C.java.
However, when testing this, I found some interesting nuances:
class Foo1 {
private int bar1;
public static class Foo2 extends Foo1 {
public void p() {
System.out.println(bar1); // illegal
System.out.println(((Foo1)this).bar1); // works
}
}
}
bar1 is visible, even though it's a private field in the superclass; it's not inherited, but you can access it by telling the compiler to look at the Foo2 object as a Foo1. But just referring to bar1 by itself fails; Java interprets this as an attempt to get the bar1 of the enclosing instance (not the superclass), but Foo2 is static, so there is no enclosing instance.
Note that if Foo2 were declared outside Foo1, the second println would be illegal, because now bar1 is not visible at all, since it's private. The moral here is that "inheritance" and "visibility" (or "access") aren't the same thing. The same thing applies to anonymous inner classes. If you use one in a place where the private instance field is visible, then you can refer to the field; if you use it in a place where the private instance field is not visible, then you can't. The location of the class declaration is more important than the type of class (nested/inner/anonymous) for this purpose.
Suppose we take away the static keyword and make it an inner class:
public class Foo1 {
private int bar1;
public Foo1(int x) {
bar1 = x;
}
public class Foo2 extends Foo1 {
public Foo2(int x) {
super(x * 10);
}
public void show() {
System.out.println("bar1 = " + bar1);
System.out.println("((Foo1)this).bar1 = " + ((Foo1)this).bar1);
System.out.println("Foo1.this.bar1 = " + Foo1.this.bar1);
}
}
}
public class Test64 {
public static void main(String[] args) {
Foo1 f1 = new Foo1(5);
Foo1.Foo2 f2 = f1.new Foo2(6);
f2.show();
}
}
Now a Foo2 object is also a Foo1; but since it's an inner class, a Foo2 instance also has an enclosing instance that is a different Foo1 object. When we create our Foo2, it users a superclass constructor to set the superclass bar1 to 60. However, it also has an enclosing instance whose bar1 is 5. show() displays this output:
bar1 = 5
((Foo1)this).bar1 = 60
Foo1.this.bar1 = 5
So just bar1 by itself refers to the field in the enclosing instance.

Singletons, Enums and anonymous inner classes

As you may know, some people are declaring singletons with an Enum of 1 instance, because the JVM guarantees that there will always be a single instance with no concurrency problems to handle...
Thus what about an Enum with multiple instances?
Can we say something like an Enum is a kind of ordered set of singletons sharing a common interface?
Why?
public enum EnumPriceType {
WITH_TAXES {
#Override
public float getPrice(float input) {
return input*1.20f;
}
public String getFormattedPrice(float input) {
return input*1.20f + " €";
}
},
WITHOUT_TAXES {
#Override
public float getPrice(float input) {
return input;
}
},
;
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
In this code why this doesn't work:
WITH_TAXES.getFormattedPrice(33f);
What is the interest of declaring a public method if it can't be called without passing through the common interface?
I guess this is why i don't see any syntax to be able to declare an interface just for one of the instances of an Enum.
Edit:
It seems that enum instances are a special kind of anonymous classes.
Thus i understand why you can't call that method.
My question is kinda related to: why can't an anonymous class implement an interface (in addition to the interface it may already implement!)
I totally understand why we CANT do that:
Vehicle veh = new Vehicle() {
public String getName() {
return "toto";
}
};
veh.getName();
(getName here is not an override)
Why i don't understand is why we can't do that with anonymous classes:
Runnable veh = new Vehicle() implements Runnable {
#Override
public void run() {
System.out.println("i run!");
}
};
veh.run();
Or something that would result in the same thing.
Think about it: if you do not use anonymous classes you can absolutely extend the Vehicle class and then make that subclass implement any other interfaces you want...
I'm pretty sure that if it was possible we would be able to call WITH_TAXES.getFormattedPrice(33f) in a typesafe way, since WITH_TAXES would not be a real EnumPriceType but it would but a subclass of EnumPriceType, with its own interface, and by calling WITH_TAXES.getFormattedPrice(33f) with a hardcoded WITH_TAXES, you know at compile that which EnumPriceType child you are calling.
So my question is: are there any reasons why this is not possible? Or it just haven't be done yet?
Your enum is equivalent to the following normal class (in fact, that's pretty much what the compiler turns it into):
public abstract class EnumPriceType {
public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
//getPrice() {...}
//getFormattedPrice() {...}
};
public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
//getPrice() {...}
};
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
The getFormattedPrice() method is unavailable on the abstract type, and therefore can't be called from the main method. Consider what would happen if the main method is rewritten to use a local variable:
public static void main(String[] args) {
EnumPriceType foo = EnumPriceType.WITH_TAXES;
foo.getFormattedPrice(33f);
}
This doesn't compile because getFormattedPrice() is not available on the base class. Since the WITH_TAXES instance is an anonymous subclass of EnumPriceType, there's no way you can define the local variable to a type where the getFormattedPrice() method is visible.
As a meta observation, this is a key difference between strongly typed languages such as Java and "duck typed" languages such as Ruby. Ruby will happily invoke the getFormattedPrice() method if happens to be there, regardless of what type of object is held in the foo variable.
As another meta observation, it doesn't make much sense for different constants of the same enum to have different sets methods. If you can't put everything you need as abstract (or concrete) methods on the base enum type, you're probably using the wrong tool to solve the problem.
Add
public String getFormattedPrice(float input) {
return input + " €";
}
outside the overrides as the default implementation. (Next to the declaration of getPrice.) And you are good to go.
You can also have enums implement interfaces, to define what everybody needs to implement.
Thus what about an Enum with multiple instances?
There is no such thing, and your example doesn't demonstrate it. You have an Enum with multiple values. They are all singletons.

Categories

Resources