Access outer class from inner class: Why is it done this way? - java

So most of us know how to access an outer class from an inner class. Searches with those words give oodles of answered questions on that topic. But what I want to know is why the syntax is the way it is.
Example:
public class A
{
private class B
{
public void c()
{A.this.d();}
public void d()
{System.out.println("You called the d() in the B class! Oh noes!");}
}
public void d()
{System.out.println("You've called d()! Go, you!");}
}
Why is it A.this.d()? It looks like this is a static field of class A, but... * am confused *
Forgive me if this is a repeat; like I said, searches with those words give how-answers.

A non-static inner class is always associated with a specific instance of the outer class. The A.this syntax is just a way to refer to this instance. I cannot think of any other simpler or clearer way of doing this. My first reaction when I saw this syntax was "ouch, ugly", but when I though a little about it I realized that it was pretty neat.
(Yes, it does look like accessing a static field, but then again, you cannot have a static field this, so it isn't ambiguous.)

I think it's just a simple way of clarifying which this one means (since this, without the qualifier, refers to the inner this which is a reference to an object of type B).
Since this is a reserved keyword it can't be confused with some static filed/method of class A.
I supposed they could have introduced some other keyword like enclosing and let you go through enclosing.this (similar to the super keyword). I just don't think they saw it as necessary to introduce a new keyword in this situation.
Would you prefer some other syntax?

Why is it done that way? Really, it's just because of the way it is. It works, it sort of makes sense, and there's no need to come up with fancy syntax to do the job.
When you see something like this:
x.y.z
The . can mean a lot of things:
Subpackage separator
Member field access
Nested type separator
In other words, the . is overloaded to serve many grammatical functions within Java programming language. It may lead to confusion, and it can be problematic, but that's just the way it is.
It helps to follow naming convention, but certain things can still look ambiguous and/or confusing.
See also
Sun Naming Conventions
JLS 6.5 Determining the Meaning of a Name
This section has many examples showing how names can be resolved

Related

How to get the defining class instance from the SubClass instance?

If i have this code:
public class MySuperClass {
public String superString = "hello";
public MyChildClass makeChild() {
return new MyChildClass();
}
public class MyChildClass {
public String childString = "hi";
}
}
How can i get the MySuperClass instance from the MyChildClass instance?
Because i have this error:
There are VERY similar questions around stackoverflow, but this isn't a duplicate of any of them.
What is the mistake in my code? How can i achieve what i said above, without making a method in the nested class which returns MySuperClass.this ? Imagine i do not own the code of MySuperClass...
I think this can be done because in the MyChildClass i can access the super instance with MySuperClass.this, how can i get the MySuperClass instance attached to the child, from outside of the child class?
EDIT: i know casting is not the way to achieve this, it was an attempt to achieve what i wanted
You're mixing terms. "Child class" is pretty much always used for this relationship:
public class Parent {}
public class Child extends Parent {}
(And 'Parent' here, is termed the 'superclass' of Child).
In that context, 'how can I get my superclass from my child class' makes no sense. Child is an extension of Parent, when you write new Child() there is just one instance, and that one instance is a combination of the stuff in Child and in Parent. It's not 2 separate things.
What you're talking about are inner classes. This relationship:
public class Outer {
public class Inner {}
}
Inner/Outer, vs. Child/Parent or Sub/Super.
So, what you actually ask is: How do I get the outer class instance?
That is not possible. It is an implementation detail of Inner, and it is up to Inner to expose this. If it doesn't want to, you don't get to access it.
But there are hacks and workarounds.
Option #1: The code in Inner itself can do it
Within the {} that go with class Inner {} you can do it:
class Outer {
class Inner {
public Outer getOuterInstance() {
return Outer.this;
}
}
}
Option #2: Hack it
At the class/JVM level, inner/outer classes don't exist. They're all just classes. That's why, if you compile the above, you end up with 2 class files, not one: Outer.class as well as Outer$Inner.class. The outer instance that Inner has is represented by a field.
This field is generally called this$0, and is package private. So, something like:
Field f = Inner.class.getDeclaredField("this$0");
f.setAccessible(true);
Outer outer = (Outer) f.get(instanceOfInner);
But, in case the reflection code didn't already spell this out for you: Don't. This is horrible idea. A SecurityManager can stop you. The code is hard to read, this$0 doesn't make sense unless you riddle this with comments explaining what you're doing. Most of all, like any reflection, this is flat out not something the author of Outer/Inner intended for you to do, and whatever you use Outer for may simply not 'work' properly in some minor point release down the road, because you're not using this library in its intended fashion, therefore any support offered for it is lost. You pave your own road, which is bad, because you have no idea what the author truly intended, and you now effectively have to say that your libraries must never be updated without extensive testing, and not updating is a great formula to get yourself hacked. It's a bad idea in so many ways.
Also, the significantly reduced care for backwards compatibility as expressed by the current OpenJDK team (see project jigsaw which was the most breaking release of java in a good long while, how OpenJDK team almost decided to get rid of the SecurityManager within a single version jump until called back by the community, aggressive expansion of mostly pointless 'opens' checks, and more) - means that if you rely on this, don't be surprised if java18 or what not breaks your ability to do this, permanently.
So, do NOT do this.
Caveat: non-static inner classes bad.
The idea that the inner class actually has an invisible field of type outer is annoying and surprising. It stops garbage collection. It confuses your average java programmer because 'using' this java feature the way it was intended is very rare.
I therefore strongly suggest you always make your inner classes static, and if you really want an instance of Outer, make it explicit: Make Inner static, then give it a private final Outer outer; field.
It's equally efficient, it's very slightly more typing, but it is a lot more readable.

Java using "extends" with scope-resolution/"dot" operator?

I just came across this while reading some code and I have absolutely no idea what it means. I tried googling and whatnot but I got nothing, probably due to a lack of vocabulary. The code:
public final class GeneralPath extends Path2D.Float
{
// code and whathaveyou
}
What I know so far:
So I dont have any questions regarding the "public final class ClassName extends" portion, but I don't understand the presence of the dot/scope-resolution operator in the superclass designation. For starters, I imagine that someone is going to say something like "Java doesn't have a scope-resolution operator" to clarify some difference in nuances between Java and Cpp/other-OOP-languages, which is fine, as I appreciate knowing subtle distinctions like that. The "private" keyword killed me in a hw assignment once and I wish someone had noted the difference between "private" in Java and C then.
Im confused because clearly it is not referencing a member of the superclass, as the "member" is capitalized, and even if it were, it would seem redundant to reference a member of an object rather than just the object class itself. Furthermore, I failed to find information on the subject since most people who write java how-to's tend to start with the simpler concepts like "basic" class inheritance, and so I couldn't find anything involving the "dot" operator in relation to using the "extends" keyword.
In case I am using too many technical terms, I want to know why they used the dot operator for "Path2D.Float", or at least, what the dot operator does in this context.
Thanks a million!
The GeneralPath class is extending a class Float that is nested inside the Path2D class, which is defined something like this:
public class Path2D {
public static class Float {
// ...
}
// ...
}

Public static methods - a bad sign?

I've just read this article here: http://hamletdarcy.blogspot.com/2008/04/10-best-idea-inspections-youre-not.html, and the last bit in particular got me thinking about my code, specifically the advice:
What in the world is a public method doing on your object that has no dependency on any fields within the object? This is certainly a code smell. The problem is that the "auto-fix" for the inspection is to apply the static keyword. Nooooo. That's not what you want to do. A public method without any dependency on object state can't possibly be part of an object that has one clearly stated charter. It's just not cohesive and should be placed somewhere else. So: if the method is private, accept the auto-fix, but if the method is public then don't.
The code in question is essentially an object transformer. It takes an object of type A and converts it to a different type.
My hierarchy is like this:
Interface ObjectTransformer -> GenericObjectTransformer
and then below this, GenericObjectTransformer is extended by ObjectTransformerA and ObjectTransformerB
Now, some functionality is required by both ObjectTransformerA and ObjectTransformerB, but doesnt actually depend on any instance variables of GenericObjectTransformer, so its a protected static method in GenericObjectTransformer.
Is this a violation of the rule above? Obviously this is protected rather than public, but its still a method accessible from outside of the class that has nothing to do with the class itself?
Any thoughts?
I disagree with the excerpt you pulled.
A public method without any dependency on object state can't possibly be part of an object that has one clearly stated charter. It's just not cohesive and should be placed somewhere else. So: if the method is private, accept the auto-fix, but if the method is public then don't.
Just because a method is static and has no relation to state, doesn't mean it falls under the "low cohesion" category. Cohesion/Functionality isn't based on state.
When you are trying to determine Cohesiveness think about the role of the class as a whole, not just the instance variables. If the logic you are looking at is related to the generic concept (GenericObjectTransformer) then leave it there.
If it is a routine to calculate the orbit of the moon, or the depth of the ocean move it to a utility class (another smelly area of our field).
It feels slightly unclean, but is seem preferable to the alternatives I can think of.
I think that the original
A public method without any dependency
on object state can't possibly be part
of an object that has one clearly
stated charter.
You reference is too black and white, and your situation is even greyer.
By having your protected method you are nicely documenting that its intended for use by derived classes. If you don't put it in the base class, then presumbly it's got to go in some ObjectTransformUtility class. Is that win? More artefacts, more places to look.
One thought: if your ObjectTransormer class undergoes significant change then how likely are you to need to change these utility methods. After all if their business is to work agains the object's interface then in fact their cohesion is quite high.

What's the catch to create _names _of _fields _like _these in java?

From time to time I see something like this:
class Clazz {
private int _goodName;
private int _anotherGoodName;
...
}
I don't get it. It's hard and unusual to read such code. What are the pros?
It's a naming convention used by some people to indicate "these are private variables".
Personally I'm not a fan as I think you can leave off the underscore and achieve the same result, but to each his own. I think it may have it's roots in pre-IDE days when you might be viewing a method and the visibility/ownership of certain variables is not always clear.
The examples of members and methods prefixed with an underscore I've seen use the convention to indicate that you shouldn't touch that member or method, when you can't make it private. I read it as 'here be dragons', never had a reason to use it myself.
An example is the _jspService() method in servlet development. Check out the linked JavaDocs.
It's just a matter of preference. Some people like to add a '_' to all private members variables of a class, other's dont. I personally do not like it but again it's preference.
Naming conventions are all about what's comfortable for the person writing the code to read/replicate (though they should be about whats easy for everyone to read)
I have a friend who uses this convention along with something like:
private int m_myVariable;
for all of his fields etc. It denotes it as a member of the particular class you're looking in but it gets very very annoying to read if you don't do the same.
If it is a likely scenario that you could have a member variable, a property and a parameter all refer to the same thing, it makes perfect sense to distinguish:
private string _myVariable;
public MyClass(string myVariable)
{
//do stuff.
_myVariable = myVariable;
}
public string MyVariable
{
get
{
return _myVariable;
}
}
I used to use these conventions in my code:
Non-final, static fields begin with an underscore.
private static SomethingOrOther _goodName;
Parameters end with an underscore.
public void doSomething(Object goodParam_, String stringToo_) {
}
And while you may consider it hard to read in the declaration of the variable, the point is to make sure they pop when reading the code in which they're used and to ensure that they are always different than any non-static fields, parameters and locally defined variables.
Another benefit of standards like this, i think, is when others come along to modify the code, they can quickly identify static fields and parameters which makes comprehension of the code happen more readily rather than having to always refer back to definitions.
I don't generally consider a convention for instance fields because access to them is almost exclusively through s/getters.
I've moved away from this with Java code, preferring instead to have my IDE always fully qualify with this for instance fields and with the class name for static fields and always using final on every variable that doesn't change, even method parameters. The interesting thing about going this route is that it encourages good naming practice, at least for me, because i like my variables to read nicely when prefixed with this or the class name.

Private variables/methods in anonymous class?

I have created an anonymous class in which I declare a few variables and methods. My java teacher tells me to make these private. I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway, so I prefer to have no modifier at all. Who is right and what makes more sense? See below for example code where I choose no modifier for 'map' and 'convert' rather than making them private.
Collections.sort(list, new Comparator<String>(){
public int compare(String a, String b){
return convert(a).compareTo(convert(b));
}
Map<String, String> map = new HashMap<String, String>();
String convert(String s) {
String u = map.get(s);
if (u == null)
map.put(s, u = s.toUpperCase());
return u;
}
});
I would be tempted to make them private simply for the fact that if you refactor the code and pull the anonymous class out as a standard class (Intellij, for example, can do this at the click of a button), having private fields is what you really want. You won't have to go and rework your classes to match your standard.
Personally I would make them private (and final where possible) anyway - it's just a good habit to be in in general.
To put it another way: if you had to put an access modifier on (if, say, the keyword package was also used as an access modifier) what would you choose? Private, presumably - after all, you don't actually want to grant any other class access, do you?
Now, having decided that private is the most logically appropriate access modifier, I would make that explicit in the code.
Then again, I'd quite possibly not create an anonymous inner class with a member variable anyway - I'd be tempted to turn that into a named nested class instead.
Your professor is right.
Make all class variable private and expose them via properties (if not anonymous).
The general rule of thumb is to keep member data such as variable including your Map object private.
Default modifier is not the same as the private modifier, there're subtle differences.
However, in your case it's more a religious question whether to make convert() default or private. I don't see any advantage in making it private though.
Anyway, your code has a memory leak as the String Cache is never cleared :-P
Also, for even shorter/less code, use the Comparator String.CASE_INSENSITIVE_ORDER:
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
It really doesn't matter, but it's probably a good idea to keep your teacher happy as he/she will be grading you.
I'd say it's a matter of style. You can't access the member map outside out of the anonymous class, but it might be best to define them as private for consistency with other classes.
If this were my code, I would say that if a class is complicated enough to need data members, it might be worth pulling it out into a separate class, in which case I'd certainly make the data members private.
The key point is when you say "I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway"... you're assuming a lot about how your class is going to be used. Treat every class like it will be passed around and used in a variety of ways, in other words, use modifiers as appropriate. Besides, it makes the intent of class clear. It's not like Java is a terse language anyway, so you might as well be clear.
I don't see much benefit to marking things private just for the hell of it. It won't really gain you anything and someone reading the code might attach some significance to the choice when there really isn't any.
I would question the need for all this complexity. Take a look at: String.compareToIgnoreCase()
You want these fields to be private, so mark them private.If a member is marked neither public not private then something suspicious is going on. Also mark fields that shouldn't change final. Keeping things standardised means less thinking, or at least less thinking on the irrelevant, and less to change when modifying code.
From a language point of view, the only real difference is that if you have extended a base class in the same package, you have now hidden fields or overridden "package-private" (default access) methods. The members can also be accessed via reflection (without setAccessible) by code in the same package (this can have mobile-code security implications).
difference between default and protected.
protected:
object/method is accessible to all classes that are in the same package, and also accessible to sub/extension classes.
default:
object/method is accessible to all classes that are in the same package.
What is your intention of your object/method and code modifier accordingly.
Do not allow yourself to be confused when you come back to the code after six months because in huge projects you want to know that that object/method is or is not accessed anywhere else.
In three weeks, not just months, you would forget what the intended accessibility of those objects, 101% guaranteed. Then if you had a huge project and you had a hundred modifiers that were not specific and you desperately wanted to update the code, you would be frustrated by the compulsion to run reference check on those 100 objects/methods. May be someone took your jar and found the hidden cookies in them and used them, then you changed your code and broke someone's code.
Code your modifiers according to your intention unless you are either one or more of these:
you have no further desire to work
in large java projects.
you are a
extremely intelligent high
functioning autistic person who has
an indexed memory of every event of
your life and can write a completely functional peer-peer file sharing service
within two weeks on a lap top in a
coffee shop.
you deliberately use it
as another tool to obfuscate your
code.

Categories

Resources