The following code works & runs perfectly.
public class Complex {
private int real, imag;
Complex(int r, int i) {
real = r;
imag = i;
}
public static Complex add(Complex c1, Complex c2) {
return new Complex(c1.real + c2.real, c1.imag + c2.imag);
}
public String toString() {
return real + "+i" + imag;
}
public static void main(String[] args) {
Integer.parseInt("5");
System.out.println(Complex.add(new Complex(2, 3), new Complex(3, 4)));
}
}
Now according to Object oriented design model, private instance members shouldn't be accessed through a object reference (which has been done here by c1.real ).
So, in that sense,there should be compiler error. But it doesn't object.
Now according to my understanding it's allowed because
c1.real code is written in the body of the private class Complex class itself.
Developer of Complex class should have access to all instance members [be it private,protected whatever] when accessing through an object reference, since Developer knows very well what he's doing unlike any third party. That's why object oriented model model isn't followed here.
Can anyone suggest a better explanation about why c1.real code is allowed here?
private means it cannot be access from another outer class. It is class based, not object based security. Note: classes in the same outer class can access private member of any other class in that file.
http://vanillajava.blogspot.co.uk/2012/02/outer-class-local-access.html
The short answer is that because that's the way Java defined the private access modifier.
The longer answer is that they probably assumed that strict encapsulation only makes sense above source file level, so even an inner class can access private members of its outer class (and vice versa): it simply makes no sense to hide members within the same source file. If you've got access to the source file of a class, you can easily modify any access modifiers anyway.
(Although the inner-outer class thing is achieved via synthetic accessors, but they're almost completely transparent.)
Related
I was supposed to write this code so that ArrIg is a static nested class of Pair. However, I declared them as independent classes, but the code still ran as expected. I understand why it still ran.
I understand that static prevents the ArrIg object from being called once Pair is called(assuming ArrIg was a nested class of Pair). Further, this violated the syntax for static nested class, but it still worked. What are some of the dangers I have exposed this code to ?
public class ClassPair {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] Ig= {1,2,3,4};
Pair pair= ArrIg.minmax(Ig);
System.out.print("min :"+pair.getFirst()+" | max :"+pair.getSecond());
}
}
class Pair {
public Pair(int a, int b){
first=a;
second=b;
}
public int getFirst(){
return first;
}
public int getSecond(){
return second;
}
private int first, second=0;
}
class ArrIg{
public static Pair minmax(int [] a){
int min= a[0];//1
int max=a[0];//1
for(int i=0; i<a.length;i++){
if (min>a[i]) min =a[i];//1
if (max<a[i]) max=a[i];//2,3,4
}
return new Pair(min ,max);
}
}
Access modifiers and nested classes are not a security mechanism. Indeed, it is pretty much trivial to circumvent them via reflection. (The only scenario where it might matter is if you are attempting to implement a system with a security sandbox.
The real purpose for access modifiers and nested classes is to provide encapsulation. It is about is about design leakage (unwanted dependencies) rather than information leakage and more general security concerns.
In this particular example, the (hypothethical) danger is that Pair could be instantiated and used outside of the ClassPair encapsulation. That could (hypothetically) be harmful, but for something like the Pair class allowing this could be a good thing.
I would also add that you need to use the terminology properly if you want people to understand what you are saying. For instance "calling" an object is not meaningful. You call methods ... not objects.
I want to create data structures to capture the following ideas:
In a game, I want to have a generic Skill class that captures general information like skill id, cool down time, mana cost, etc.
Then I want to have specific skills that define actual interaction and behaviours. So these would all extend from base class Skill.
Finally, each player will have instances of these specific skills, so I can check each player's skill status, whether a player used it recently, etc.
So I have an abstract superclass Skill that defines some static variables, which all skills have in common, and then for each individual skill that extends Skill, I use a static block to reassign the static variables. So I have the following pattern:
class A {
static int x = 0;
}
class B extends A {
static {
x = 1;
}
}
...
// in a method
A b = new B();
System.out.println(b.x);
The above prints 1, which is exactly the behaviour I want. My only problem is that the system complains about I'm accessing static variable in a non-static way. But of course I can't access it in that way, because I only want to treat the skill as Skill without knowing exactly which subclass it is. So I have to suppress the warning every time I do this, which leads me to think whether there is a better/neater design pattern here.
I have thought about making the variables in question non-static, but because they should be static across all instances of the specific skill, I feel like it should be a static variable...
You should generally avoid such use of global state. If you know for sure that the field x will be shared across all instances of all subtypes of the base class, then the correct place to put such a field is probably somewhere other than the base class. It may be in some other configuration object.
But even with your current configuration, it just does't make sense since any subclass that modifies the static variable will make the variable visible to all classes. If subclass B changes x to 1, then subclass C changes it to 2, the new value would be visible to B as well.
I think that the way you described in the question, every subclass should have its own separate static field. And in the abstract base class, you can define a method to be implemented by each subclass in order to access each field:
abstract class A {
public abstract int getX();
}
class B extends A {
public static int x = 1;
public int getX() {
return x;
}
}
class C extends A {
public static int x = 2;
public int getX() {
return x;
}
}
As already pointed out by some answers and comments, your approach won't work the way you want because every static block changes the static variable for all classes extending A.
Use an interface and instance methods instead:
public interface A {
int getX();
}
-
public class B implements A {
private static final int X = 1;
#Override
public int getX() {
return X;
}
}
-
A myInstance = new B();
System.out.println(myInstance.getX()); // prints "1"
I want to know how many instances of a static member class can be created by the enclosing class. I assume one only, but then the following extract from Bloch doesn't make sense to me.
Quoting Joshua Bloch's Effective Java - Item 22*: Favor static member classes over nonstatic.
A common use of private static member classes is to represent components of the object represented by their enclosing class. For example, consider a Map instance, which associates keys with values. Many Map implementations have an internal Entry object for each key-value pair in the map. While each entry is associated with a map, the methods on an entry (getKey, getValue and setValue) do not need access to the map. Therefore, it would be wasteful to use a nonstatic member class to represent entries: a private static member class is best. If you accidentally omit the static modifier in the entry declaration, the map will still work, but each entry will contain a superfluous reference to the map, which wastes space and time.
He states that the map creates an Entry object for each key-value pair in the map, i.e. multiple instances of the static member class.
So my assumption is wrong! That means my understanding of static member classes is wrong. Everyone knows how a static member variable behaves, the classic static final string for instance - there is only one instance of the object.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API? Every other Collections class could then just provide it's own implementation.
[*] Just realised that it's item 18 in the PDF version of the book I have
This is a common misinterpretation of the static keyword.
When you use static with a variable it means there will be only one of these for all objects of this class or something like that.
static Object thereWillBeOnlyOne = new Object();
However, in the context of inner classes it means something completely different. A static inner class has no connection with an object of the enclosing class while a non-static inner class does.
A static inner class:
public class TrieMap<K extends CharSequence, V> extends AbstractMap<K, V> implements Map<K, V> {
private static class Entry<K extends CharSequence, V> implements Map.Entry<K, V> {
The Map.Entry class used by my TrieMap class does not need to refer to the object that created it so it can be made static to save the unnecessary reference.
A non-static inner class:
public final class StringWalker implements Iterable<Character> {
// The iteree
private final String s;
// Where to get the first character from.
private final int start;
// What to add to i (usually +/- 1).
private final int step;
// What should i be when we stop.
private final int stop;
// The Character iterator.
private final class CharacterIterator implements Iterator<Character> {
// Where I am.
private int i;
// The next character.
private Character next = null;
CharacterIterator() {
// Start at the start.
i = start;
}
public boolean hasNext() {
if (next == null) {
if (step > 0 ? i < stop : i > stop) {
next = s.charAt(i);
i += step;
}
}
return next != null;
}
The CharacterIterator inside a StringWalker object refers to the string to be iterated as s which only exists once in the StringWalker object. I can therefore create many iterators of a StringWalker and they all walk the same string.
Why this weirdness?
This seemingly illogical duality derives from the use of the static keyword in C.
In C you can (or at least used to be able to) do:
void doSomething () {
static int x = 1;
if ( x < 3 ) {
} else {
}
x += 1;
}
and each time you called the function, x would be as you left it last time around - incremented in this case.
The concept was that the static keyword indicated that the variable was scopefully enclosed by its enclosing block but semantically enclosed by its parent block. I.e. the above code was roughly equivalent to:
int x = 1;
void doSomething () {
if ( x < 3 ) {
} else {
}
x += 1;
}
but x was only allowed to be referenced inside the function.
Take that concept forward into Java and things now make a little more sense. A static inner class behaves exactly like it was declared outside the class while a non-static inner bonds much more tightly to its enclosing instance - in fact it can refer to the instance directly.
Also:
class Thing {
static Object thereWillBeOnlyOne = new Object();
behaves much like
Object thereWillBeOnlyOne = new Object();
class Thing {
if it were legal.
Here endeth the lesson.
I think the Java team messed up the naming on this one. A static inner class (strictly speaking their correct name is "static nested class") is in no way different from an ordinary class except it has a fancy name (Something.MyClass instead of MyClass) and can be made private (i.e. not instantiable from other classes).
In case of Map, it was solely chosen because the name Map.Entry makes it clear that Entry relates to Map. As you suggest, it would have been perfectly reasonable to just use an ordinary class for this. The only difference is you don't get to write Map.Entry.
I think what they should have done is to use the syntax for "non-static" inner classes (i.e. just class in an enclosing class) for static nested classes, and instead invent a new keyword to create "non-static" inner classes, because it's these that behave different from normal classes. Maybe something like attached class. AFAIK the keyword static was chosen in order to avoid having too many reserved keywords, but I think it just encouraged confusion.
Yes, you can have many instances of the nested class, no matter that the nested class is static.
When the nested class is static you can create instances of it without having an instance of the enclosing class, this is one of the benefits, and basically the main difference between static and non-static nested classes.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
It's instantiated when it's constructor is called. Not any different from non-static classes. The nested class itself is loaded by the JVM, when the code first accesses it. Again this is not any different when compared to other classes, I think (not 100% sure of this though, but you can test it yourself). So I think you're kind of mixing the terms "loading the class by the JVM" and "instantiating the class".
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API?
As said, it's easier to create instances of static nested classes. You don't need an enclosing instance which is sometimes (maybe most of the times) exactly what you want.
See also:
(1) Nested Classes
(2) How can the JVM decide if a class is nested into another class?
(3) Loading of a nested class by the JVM
You can search for other references along these lines.
The reference (2) seems advanced and kind of peripheral to your question.
what's the point of Map using a static member class for Entry?
That's because, it makes the package structure logically correct.
Why not just use an interface on the API?
Now, this is a design discussion nobody would like to be dragged into.
I have done some searching on the difference in implementing a closure using an anonymous class and a local class. I am trying to figure out all the differences between the two so I know which method is better in which situations.
Correct me if I am wrong:
The anonymous class has a class instance and object instance created each time a new instance is created.
The local class has only an object instance create each time a new instance is created.
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
EDIT: It appears there is no real difference between the two, just depends on style and if you want to reuse the class.
To clarify what I mean here is an example of what I am talking about:
public class ClosureExample {
interface Function {
void func(int value);
}
public static void main(final String[] args) {
final Function local1 = localClassClosure("Local1");
final Function local2 = localClassClosure("Local2");
final Function anonymous1 = anonymousClassClosure("Annonymous1");
final Function anonymous2 = anonymousClassClosure("Annonymous2");
for (int i = 0; i < 3; i++) {
local1.func(i);
local2.func(i);
anonymous1.func(i);
anonymous2.func(i);
}
}
private static Function localClassClosure(final String text) {
// Local class name is irrelevant in this example
class _ implements Function {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
}
return new _();
}
private static Function anonymousClassClosure(final String text) {
return new Function() {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
};
}
}
Hopefully, someone can explain in detail this subtle difference and which method should be used in which situations.
This piqued my interest, and I broke out JD-GUI to look at the decompiled classes. There is actually no difference at all between the two anonymous inner classes after compilation:
localClass:
class ClosureExample$1t implements ClosureExample.Function{
ClosureExample$1t(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
anonymousClass:
class ClosureExample$1 implements ClosureExample.Function{
ClosureExample$1(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
Both methods are valid ways of implementing an anonymous inner class, and they seem to do the exact same thing.
EDIT: I renamed the _ class to t
I am pretty sure there is nothing like object instance, just class instance .
So yes an object is created for both local and anonymous types..
The difference however is you can't reuse the anonymous class (except through the way you used it in your method - which works but not really maintainable), so you use it when whatever you are doing is a one off thing. For example with event listeners.
I would prefer named types to anonymous types though.
You might find this useful
EDIT:
You will find my question here useful.
Just a note about this:
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
If you need to quickly setup an event listener [e.g. a KeyListener] inside a component, you can do like this:
addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent ke){ ... }
// further implementation here
});
Though it won't be reusable at all.
The local class object is faster at initialization (because the class is already in memory at startup)
The anonymous class object less memory consuming (because of the lazy evaluation)
Notice : Because java is not a real functional language. Anonymous classes will be pre-evaluated and even stored in class files. So really there wont be much difference.
In a functional language, like scheme :
(define inc (lambda (a) (lambda () (+ 1 a))))
(display ((inc 5)))
The function (lambda () (+ 1 a)) will be actually recreated at each anonymous call like ((inc 5)). This is the concept behind anonymous classes.
As opposed to:
(define inc (lambda (a) (+ 1 a)))
(display (inc 5))
Where (lambda (a) (+ 1 a)) will be stored in memory at compile time, and the call to (inc 5) will only reference it. This is the concept behind local classes.
I just discovered local classes in Java:
public final class LocalClassTest
{
public static void main(final String[] args) {
for(int i = 10; i > 0; i--) {
// Local class definition--declaring a new class local to the for-loop
class DecrementingCounter {
private int m_countFrom;
public DecrementingCounter(final int p_countFrom) {
m_countFrom = p_countFrom;
}
public void count() {
for (int c = m_countFrom; c > 0; c--) {
System.out.print(c + " ");
}
System.out.println();
}
}
// Use the local class
DecrementingCounter dc = new DecrementingCounter(i);
dc.count();
}
}
}
I did come across this comment: Advantages of Local Classes which listed some great advantages of local classes over anonymous inner classes.
My question is, it doesn't seem like there would be many cases where this technique would have advantages over NON-anonymous inner classes. What I mean is: you would use a local class if your class is only useful inside a method's scope. But when your methods get to the point they are so complex you need to start defining custom classes inside of them, they are probably far too complex already, and need to be split up. At which point, your local class would have to become an inner class, right?
What are some examples of when local classes are more desirable than inner classes, which don't involved super-complex methods (which should be avoided)?
Local class is something used in some particular method and nowhere else.
Let me provide an example, I used a local class in my JPEG decoder/encoder, when I read configurations from the file which will determine further decoding process. It looked like this:
class DecodeConfig {
int compId;
int dcTableId;
int acTableId;
}
Basically it is just three ints grouped together. I needed an array of configurations, that's why I couldn't use just an anonymous class. If I had been coding in C, I would've used a structure.
I could do this with an inner class, but all the decoding process is handled in a single method and I don't need to use configurations anywhere else. That's why a local class would be sufficient.
This is, of course, the most basic example, but it's from the real life.