Referencing an enclosing instance from an inner class - java

This is a knowledge/curiosity question only.
After several years in Java, this has only just struck me.
class Foo {
class Bar{
Foo.this.doSomething();
}
}
When I look at Foo.this, I would assume that it's a static reference which obviously is not the case.
I know this is part of the Java spec, but exactly what is going on when you use <Class>.this?
Is it one of those "it just is" things?

I know this is part of the Java spec, but exactly what is going on when you use .this?
It just refers to a "hidden" field within Bar. It's easiest to see this by decompiling. You'll see that there's a Bar constructor taking a reference to an instance of Foo. That reference is stored in a field, and then when you use Foo.this, it just accesses that field. So assuming you'd put your Foo.this.doSomething() into a someMethod call, your code is similar to:
class Foo {
static class Bar {
private final Foo $foo;
Bar(Foo foo) {
this.$foo = foo;
}
public void someMethod() {
$foo.doSomething();
}
}
}

Related

How to you mock a dependent class in Mockito when following Java Composition pattern?

My question may be a tad misleading but i'm not sure of any other way to ask it. Basically I'm having trouble discerning the differences between 'dependency injection' and 'java composition'. They both involve using variables to access classes. With dependency injection you pass an already instantiated instance (class A) created outside of Class B into the class B via constructor. With Java composition it seems you create a new instance of Class A inside of Class B since Class B cannot exist without Class A. If I'm interpreting this wrong then I'm not understanding the design pattern difference between dependency injection and Java composition since you have to do the same thing to use variables to access other class objects.
Anywho, using mockito, how would I go about testing this Java composition pattern?
What i'm needing help with:
Class Bar cannot exist without Class Foo (Java Composition: Has-A). therefore, i create a new instance of Foo inside bar instead of injecting an already created instance of Foo into Bar (dependency injection).
How do I properly set this up in Mockito so that I can mock a class of Foo inside Bar? My pseudocode is below.
Create interface
public interface MyRequiredObjectsInterface {
public String stringOne();
public List<String> listOne();
}
Create Class 'Foo' that implements Interface
public class Foo implements MyRequiredObjectsInterface {
public Foo() {
//Empty for example
}
#override
public String stringOne() {
return "StackOverflow Help";
}
#override
public List<String> listOne() {
return new List<String>();
}
}
Create Class 'Bar' that cannot exist without class 'Foo'
public class Bar implements MyRequiredObjectsInterface {
Private Foo foo;
public Bar() {
*/
Java composition pattern. With dependency injection, I would just pass an instance
of foo through the constructor. I dont know why you dont do this with Java composition
pattern and if you do, then I dont understand the difference in design patterns with this.
/*
foo = new Foo();
}
#override
public String stringOne() {
return foo.stringOne();
}
#override
public List<String> listOne() {
return foo.listOne();
}
}
Ok, so now I've shown you the setup. In Mockito, how would I test this Java composition patter? The following code does not work because I cannot mock an instance of Foo inside Bar since the instance is created inside Bar.
public class BarTest {
private Foo foo;
private Bar bar;
#Before
public void setUp()
this.bar = new Bar();
// There is no way to get this inside Bar...
this.foo = mock(Foo.class);
}
#test
public void testListOne() {
*/
NOTE how that if you look at the code above, it calls the object from Foo -- foo.listOne();
In a real world scenario, this would be more complicated logic here as Foo
may perform more complex logic that may need to be mocked out for testing
but to show my design of the application i used pseudocode to get the point
across to show what im struggling grasping with the Java composition design pattern.
This would run into errors since I cannot mock this with Java composition pattern.
*/
assertEquals(bar.listOne().equals(...)
}
Any thoughts on helping me solve my conundrum? Here are some references I used that didnt answer my question
Difference between dependency and composition?
https://www.softwaretestinghelp.com/composition-in-java/

Constructor for a class whose super should only be made via factory method

I have the following class:
public class Foo(){
int parameter;
static Set<Foo> cache=new HashSet<Foo>();
public Foo(int parameter){
this.parameter=parameter;
addToCache(this);
}
public static Foo Factory(int parameter){
Foo duplicate=findDuplicate(parameter);
if (duplicate!=null){
return duplicate;
}else{
return new Foo(parameter);
}
}
}
Notice that calling Foo's constructor directly will add to the static cache.
I now need to subclass this object to add some functionality.
public class Bar() extends Foo{
public Bar(int parameter){
//Danger
}
}
But now I'm stuck. Bar's constructor has to call super() one way or another, but that won't check for duplicates like Foo.Factory() does.
What I would really like would be something like:
public Bar(int parameter){
this=Foo.Factory(parameter);
}
But that's obviously not valid java.
For now, I have been forced to write a hacky secondary constructor for Foo that also checks for duplicates, and have Bar use that:
//Second unused parameter just so the constructors are different
public Foo(int parameter, boolean isEvil){
Foo duplicate= findDuplicate(parameter);
if (duplicate!=null){
this.copy(duplicate); //Evilly take on all attributes of duplicate
}else{
//Now we have to copy the body of the original constructor.
//It has to be kept synched forever, and I can't even call it!
this.parameter=parameter;
addToCache(this);
}
}
Bar(int parameter){
super(int,true);
}
But this has the problem of always creating a new object, which can cause mutability and hashing concerns. Furthermore, anyone not paying attention won't be able to tell that this constructor works differently.
TLDR: How do I make a constructor for a class whose super should only be made via a factory method.
Possible duplicate of this question, but in java (also that question had only one answer and it was unsatisfying to both me and OP)
The way I see it, you have two options.
Options 1 is to create a factory method for bar instead of a public constructor.
Option 2 is that, instead of making bar inherit from foo, it instead contains an instance of foo as a member. In the constructor you can call the factory method for foo.
Which way you go probably depends on the details.

Abstract int() causing an invisible halt in my application

I noticed today that a certain feature wasn't working at all in my API and it's actually devistating to the progress I'm making on my application that's using the API. There's absolutely no errors being produced, the application doesn't stop, hang, or even stutter. It justs acts as if I called return and carries on with it's processing.
The in a nutshell class:
public abstract class Foo {
private static Foo singleton;
public Foo() {
singleton = this;
}
public static Foo getSingleton() {
return singleton;
}
public abstract int bar();
}
in which I have another class that inherits from this like so:
public class Bar extends Foo {
public Bar(...) {
super...
}
#Override
public int bar() {
return 5;
}
}
Now, the class "Bar" isn't in the same project as the "Foo" class, as the "Foo" class is part of an API (.jar) that is added as a dependency; However inside the .jar I have some code that needs to reference the value set by the overriden class over bar()
The code that I'm using that currently upsets my girlfriend is below:
int foo = Foo.getSingleton().bar(); // This should return the value of 5 set earlier
Which does not set the value of foo, and in-fact doesn't even print out to the console if I add a System.out.println after it. It literally just feels like it return's
This constructor
private static Foo singleton;
public Foo() {
singleton = this;
}
which initializes the static singleton field will only be invoked if you create a new instance of a subtype of Foo, ie. Bar.
You haven't showed a new instance creation expression involving Bar, so I assume there isn't one.
As such
int foo = Foo.getSingleton().bar(); // This should return the value of 5 set earlier
can only terminate with a NullPointerException when trying to invoke bar() on the null returned by getSingleton().
If you aren't seeing the NPE, then you must be catching it and ignoring it.
Your singleton is not correctly implemented. Foo.getSingleton() will return singleton which is null at that point. The static variable is only initialized in the constructor which is never called in your example. You'll have to initialize singleton in a static context, e.g. inside your getSingleton() method with a null check:
public static Foo getSingleton() {
if(singleton == null) {
singleton = new Foo();
}
return singleton;
}
EDIT
As MihaiC correctly stated in the comments, this wouldn't work since Foo is abstract. I did miss that little detail. Considering this it really doesn't make sense to have a singleton of an abstract class, unless you try to somehow initialize it with a Bar instance. The design still feels strange to me. Still leave my answer above for now for the general concept.

Why isn't the Java compiler (specifically its parser) able to understand this statement

I have the following two classes (in two separate files).
public class Foo
{
public static class A
{
public static final boolean FLAG = false;
}
public final A A = new A();
}
public class Bar
{
void method()
{
if (Foo.A.FLAG) <<<< this is giving "Cannot make static ref to non-static field
// do something
;
}
}
My question is, why isn't the compiler able to recorgnise that by Foo.A, I meant the class A, not the member, which also happens to be named A?
This is called obscuring, an obscure feature/limitation of Java
A simple name may occur in contexts where it may potentially be
interpreted as the name of a variable, a type, or a package. In these
situations, the rules of ยง6.5 specify that a variable will be chosen
in preference to a type, and that a type will be chosen in preference
to a package. Thus, it is may sometimes be impossible to refer to a
visible type or package declaration via its simple name. We say that
such a declaration is obscured.
If the variable A was static, it would compile since you can can access static members on object references.
Also FLAG hasn't been initialized.
Some ways to access the flag:
<Foo_A extends Foo.A> void test1()
{
if(Foo_A.FLAG)
;
}
void test2()
{
class Foo_A extends Foo.A{}
if(Foo_A.FLAG)
;
}
-------------------------------------
import pkg.Foo.A;
public class Bar
{
void test3()
{
if(A.FLAG)
;
}
}
in these contexts, "Foo.A" can only be interpreted as a type, not a variable.
Because inner classes require an instance of the enclosing type. If you dont have an instance of Foo, A doesnt exist.
Edit - This is incorrect, but the reason why is informative. see the comments below:

Is it possible to access the Class object in a static method?

Consider the following Java class:
public class Foo
{
public static void doStuff()
{
// boring stuff here
}
}
Is it possible to access either the class literal Foo.class, or just the class name "Foo" from within a static method such as doStuff()? In a non-static method I would just call this.getClass(), but there is no this to use in a static method.
Edit: sorry this wasn't clear - I want to do this with explicitly using the class literal Foo.class.
Use Class<Foo> clazz = Foo.class
If you need something like:
class Foo {
static Class foo(){return the current class}
}
class Bar extends Foo {
}
and expect Bar.foo() to return Bar if called on Bar, and Foo if called on Foo - you have something wrong in your design and perhaps you need to make the methods non-static.
Unfortunately Java doesn't give you a good way to do this. You just have to reference Foo.class. This is something that is a regular annoyance for me.
For logging I solved it (the idea for the solution came from Log5j) by reading the stack, because it got really annoying to restate the class for every logger every time. Fortunately modern IDEs make it relatively painless, so that refactoring isn't really negatively impacted if you have to change the name of the class.
EDIT: Some code:
private static StackTraceElement getCallerStackTraceElement(StackTraceElement[] elements) {
for (int i = 0; i < elements.length; i++) {
if (elements[i].getClassName().equals(MyLogger.class.getName())) {
return elements[i + 1];
}
}
return null;
}
MyLogger in this case is the class where this method exists. It finds itself in the stacktrace and goes one earlier, and then extracts the class from the StackTraceElement.
The StackTraceElement[] array can be retrieved by either new Exception().getStackTrace(), or Thread.currentThread().getStackTrace(); The way this method is written it assumes the stacktrace is created on the first method call into MyLogger.
Just use Foo.class. You don't have to worry about inheritance or anything like that, since there's no object associated with a static method.
When dealing with static methods, you can think of them as libraries, where the class name becomes the library name. You tell the compiler which bar() method to run by specifying the library (class) name. Foo.bar() vs. Bar.bar().
The method itself has no parent and no instance, therefore, it can't use reflection to know what class it's part of. However, you can add a reflection method.
You can add a static method to the class that answers itself what class it's in:
public class Foo {
private static class self() {
return Foo.class;
}
public static void doStuff()
{
// Use self() to reference the Foo class
}
}
Notice that I made the self() method private because outside of the class, it makes no sense.
This works because the self() method is visible from inside the class, and inside the static method.
In contrast, PHP has a self construct to reference the current class.

Categories