How is this not a Java visibility violation - java

It is a simple implementation of linked list to split one list into two sublists. Other details have been discarded for simplicity
class SList {
private head;
Object item;
public void split_list(SList list1, SList list2) {
list1.head = this.head;
// Some other stuff
}
}
isn't it a visibility violation to do assign list1.head? To my surprise, I tried and it worked fine

The private modifier means a member can only be accessed by the class itself, it's not restricted to an instance of that class. Also see the documentation

An instance of a class always has complete access to all members of other instances of the same class, regardless of their visibility. private means private to this class, not to this object.

As per JLS 6.6.8:
A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
It's the same class.

The modifier private of the member head means private to the class SList, not private to an instance of SList (defined in JLS 6.6.8, http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.8).

Related

How is inner class initialized

Below is a piece of code which provides an example of using inner class in Java.
I would like to know how the inner class instance iterator is created and linked to the arrayOfInts array.
DataStructureIterator iterator = this.new EvenIterator();
I understand that the 'ds' instance is created by the constructor of DataStructure class, but the iterator instance is of DataStructureIterator type. It seems not quite reasonable that a DataStructureIterator instance can be constructed by a constructor of another class.
Full code here:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
public void printEven() {
// Print out values of even indices of the array
DataStructureIterator iterator = this.new EvenIterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
interface DataStructureIterator extends java.util.Iterator<Integer> { }
// Inner class implements the DataStructureIterator interface,
// which extends the Iterator<Integer> interface
private class EvenIterator implements DataStructureIterator {
// Start stepping through the array from the beginning
private int nextIndex = 0;
public boolean hasNext() {
// Check if the current element is the last in the array
return (nextIndex <= SIZE - 1);
}
public Integer next() {
// Record a value of an even index of the array
Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
// Get the next even element
nextIndex += 2;
return retValue;
}
}
public static void main(String s[]) {
// Fill the array with integer values and print out only
// values of even indices
DataStructure ds = new DataStructure();
ds.printEven();
}
}
This is a question from the Oracle's Java documents, here is the source: https://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html
From your Q:
It seems not quite reasonable that a DataStructureIterator instance can be constructed by a constructor of another class.
In your code, the instance of the DataStructureIterator is actually not created by the DataStructure constructor. It is created whenever the DataStructure instance method printEven is called:
public void printEven() {
// Print out values of even indices of the array
DataStructureIterator iterator = this.new EvenIterator();
// Omitted for brevity
}
But it could also be created in the constructor as a field or set with a default value e.g.:
public class DataStructure {
private DataStructureIterator iterator = new EvenIterator();
// Omitted for brevity
}
If your inner class (EventIterator) was public, it could also be created "outside" of DataStructure:
// In some other Java class
DataStructure ds = new DataStructure();
DataStructure.EventIterator iterator = ds.new EventIterator();
The key thing is that outer class (DataStructure) instance is created first.
As the docs note:
To instantiate an inner class, you must first instantiate the outer class
This is because the instance of an inner class is always tied to the outer/parent class.
From your Q:
I would like to know how the inner class instance iterator is created and linked to the arrayOfInts array.
The key thing is that an instance of a inner non-static class is that always has access to the parent instance's methods/fields.
As the docs also state (emphasis added):
As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields.
As such, the instance of the DataStructureIterator can access the DataStructure field arrayOfInts.
But note that if you created a separate DataStructure instance e.g. ds2, then the DataStructureIterator instance within ds2 will have access to ds2.arrayOfInts but it won't have access to the ds.arrayOfInts. In your code the values of arrayOfInts will be the same but the instances are actually different (try allowing arrayOfInts to be set via the DataStructure constructor).
If DataStructureIterator was defined as a nested static class, then it won't automatically have access to arrayOfInts and it would need arrayOfInts passed in as an arg to its constructor or to its method.
You can think of inner non-static classes as a logical grouping of code for the parent (DataStructure class) and the docs linked above outline good reasons when to use them. But in general don't use them unless you know what you're doing.
An inner class is instantiated the same as any other class is, just the scope of the class (and thus its instances) is different.
So yes, your inner class instance is created by a call inside the outer class method (not the constructor in the case of your example, but the printEvent method).
I don't know what you mean with the "ds instance is created by the constructor of DataStructure". If you mean that the class is initialised by the constructor, no.
A non-static inner class is best thought of as follows (because.. they really are exactly like this, at the class level):
They have a secret (invisible) final field of the outer type's type.
All constructors, even the default (empty) one have a secret additional parameter of the same type, and they all have an additional extra syntax sugar line at the top, in the vein of this.theFinalFieldIMentionedEarlier = thatParameter;.
Calling new InnerClass() will silently pass this along as that parameter.
If no this that fits is available, you must pass the parameter yourself. However, instead of writing new InnerClass(instanceOfOuter), you write instanceOfOuter.new InnerClass() instead. The effect is identical, and at the class level, there is no difference.
Generics is rather wonky; if the outer has it, oof.
As a consequence:
Do not use non-static inner classes unless you really know what you are doing and you understand and want this weird field. If you don't, or if you feel this is confusing (and it is; most java programmers do not know this is how it works), you might want to consider making your inner class static, and making that field explicit - i.e. handrolling this functionality. It's not particularly complicated (requires 1 field, 1 constructor parameter, and 1 this.outer = outer; statement in the constructor, not exactly a boatload of boilerplate), and clears up rather a lot.
So how does it work - exactly as if it had that field. Because, that's exactly what javac does. inner classes mostly don't exist at the class level, they just become top level classes with funky names (Outer$Inner), a boatload of synthetic methods to bridge private methods together. In newer JVMs, there's the nestmates system that avoids some of those bridges, but they're still individual top-level classes after javac is done with it.
In other words, this:
class Outer {
class Inner {
public Inner(int example) {}
}
void test() {
new Inner();
}
}
is virtually identical to:
class Outer {
static class Inner {
private final Outer outer;
public Inner(Outer outer, int example) {
this.outer = outer;
}
}
void test() {
new Inner(this);
}
}

Why static nested class?

I have a sample code for tries.The code seems have no compile errors. Why does it use static nested class node? when I delete static in Node nested class and compile, the error shows create generic array in private Node[] next = new Node[R];. What on earth happened?
public class TrieST<Value> {
private static final int R = 256; // extended ASCII
private Node root; // root of trie
private int N; // number of keys in trie
// R-way trie node
private static class Node {
private Object val;
private Node[] next = new Node[R];
}
public TrieST() {
}
}
Assuming that in your code snippet you are using a non-static inner class instead of a static nested class like this: private class Node, in that case, you will be trying to instantiate an Array which is not possible, we can't instantiate an Array in a generic class, because generics doesn't have any information regarding their type at runtime, while arrays creation expression specifies the element type.
So, the reason why using a Static Nested Class compiled, is that such classes are considered as a "top-level" class (in terms of behavior):
A static nested class interacts with the instance members of its outer
class (and other classes) just like any other top-level class. In
effect, a static nested class is behaviorally a top-level class that
has been nested in another top-level class for packaging convenience.
Now, let's take all of this into consideration, and come back to the exact error displayed by the compiler:
Cannot create a generic array of TrieST<Value>.Node
That means that the type of the array you want to create is TrieST<Value>.Node whose runtime's type is not known, thus different types may be inserted into the next array. More clear and well explained examples could be found in Cannot Create Arrays of Parameterized Types
Whereas, a static Nested class is not behaving as an inner class of TrieST<Value> , thus instiating an array inside Node will not be illegal as it's not of the type TrieST<Value>.Node, its of the type Node (like if it's a top-level class) .
Because with static you create: Node[] next = new Node[R] and with non-static inner-class you create a Node that is associated with an instance of the outer-class, which has a generic type. And creation of generic arrays is forbidden.
But lets back up a few steps: the way to instantiate an inner-class (non-static) is as follows (example):
class TrieST<V> {
private static final int R = 256;
private Node root; // root of trie
private int N; // number of keys in trie
private TrieST<String> inst = new TrieST<String>(); // must create an instance of the outer class first
// R-way trie node
private class Node {
private Object val;
private TrieST<String>.Node next = inst.new Node(); //must use an instance of the outer class to instantiate an object of the inner class
}
public TrieST() {
}
}
Now, if we'll try to change the implementation above from an instance of the inner class to an array, we'll get generic array creation because it's prohibited to create arrays with generic type due to the covariance nature of arrays (Shape[] is super of Triangle[]) which doesn't work well with the invariant nature of generics (List<Object> is not super of List<String>). In "Effective Java" Bloch provides a more detailed explanation if you want to dig in.
If you insist on using an inner-class, you can work around this restriction by using Array.newInstance() which can create array of a type known only at runtime as follows:
private Node[] next = (Node[]) Array.newInstance(Node.class, R);

Clarification of private access modifier [duplicate]

This question already has answers here:
Do objects encapsulate data so that not even other instances of the same class can access the data?
(7 answers)
Closed 9 years ago.
I am trying out the following code from Ivor Horton's Java book in which a two dimensional point is implemented via a simple class.
public class Point
{
//x and y coordinates
private xVal,yVal;
//Constructor
public Point (double x, double y)
{
this.xVal = x;
this.yVal = y;
}
//Constructor
public Point (final Point aPoint)
{
this.xVal = aPoint.xVal;
this.yVal = aPoint.yVal;
}
}
Now, the point I don't understand is that in the second constructor which takes an object of type Point as argument, the newly created Point object can access the instance variables x and y of argument Point object directly. This means that private members(methods and variables) of an object can be accessed from inside methods of another object of the same type, in addition to the methods inside the same class. Can anyone please clarify the issue because according to my understanding, the variables of the arugment object should be accessed via getter and setter because they are private.
This is the common misconception that private fields are accessible only by the same instance.
Actually, private fields are private within that class, and not for an instance. So any instance of that class can access private field when in that class.
From JLS - Section 6.6.1:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Emphasis mine.
It is private to the class, rather than private to the object.
This means other instances of the class can access private variables within an object of the same class.
The docs don't make this immediately obvious - but they do talk about access depending on class, rather than on object :
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
First of all there's an error in the code.
should be:
public class Point
{
//x and y coordinates
private xVal,yVal;
//Constructor
public Point (double x, double y)
{
this.xVal = x;
this.yVal = y;
}
//Constructor
public Point (final Point aPoint)
{
this.xVal = aPoint.xVal;
this.yVal = aPoint.yVal;
}
}
Note the second C'tor aPoint variables.
Secondly, private means private to the Class. Not the instance.
So other instances of the class can access the private members/methods.
From javadocs:
The private modifier specifies that the member can only be accessed in
its own class
You an always access private members of the class within the class anywhere including constructors.
This means that private members(methods and variables) of an object
can be accessed from inside methods of another object of the same type
Yes, this is correct. The "private" access modifier works on file level.
This means you can not only access private members from different objects but even from a different class, if one class is a nested (static or non-static), local or anonymous class of the other and if you have a valid object reference of the other class (either explicit or implicit). This works in both directions (outter <-> inner).
Note that the purpose of access restriction is making explicit the scope and range of the coupling between parts of code.
Seen in this light, private members of a class/instance should be accessible to all code enclosed by the declaration of that class—and indeed they are.

Accessing a Super's Member of different type with the same variable name

Consider the following superclass and subclass pair, how do you access the superclass member?
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
}
You can access the super Member by super.aNumber provided it is an instance of the Subclass.
Given that the attribute does not have a visiblity modifier, it is assumed to be package private. Subbie will only be able to access Super's aNumber if they're in the same package.
If it was, you could access it like this: super.aNumber. Notice super here is a keyword that implicitly refers to the superclass, and doesn't have anything to do with the superclass being named Super.
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
public Number getNumberFromSuper() {
return super.aNumber;
}
}
I'd suggest to take a read on the excellent Java tutorials online, for instance:
Inheritance
Controlling Access to Members of a Class
You can define a field with different keywords known as Access Modifiers (check the links at the end for a detailed explanation on this topic), each one defining a scope for access/use. I'll focus this explanation on fields.
Public: Accessible by everyone. This Access Modifier is regulary used with methods and not with fields. In Java, it is encouraged the use of get and set methods to access the value of a field and change it (respectively). You can access a field this way:
AClass c = new AClass();
c.publicField = 3; //Setting a value in a field, int in this case
int sum = c.publicField + 4; //Obtaining the value of publicField to use it
Private: Definining a field as private makes it visible only to the class itself, meaning no one outside the boundaries of a class will be able to see that field. A common class in Java usually has private fields and accessors (get & set methods).
public class AClass {
public int publicField;
private String privateField = "Can't see me!";
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String newValue) {
privateField = newVaule;
}
}
Getters and Setters let you control the access to your private fields, allowing you to perform any logic you desire before updating the value of that field or preparing a field in a particular before returning its value if you need it.
Protected: Only subclasses of a class and classes in the same package can access a field defined with this keyword. In your case Subbie has access to the protected fields of Super and any other class in the same package as Super has access to those fields as well.
No Access Modifier: This is your current case and the answer to your question relies strongly on the structure of your classes. If they are in the same package, then you can access Super's field from Subbie. Otherwise, if Subbie is in another package, you won't be able to access that field. This field is referenced as Package-Private.
Some related articles you might want to check:
Inheritance in Java
Controlling the Access to Members of a Class

Java Final arraylist

My question is regarding declaring an arraylist as final. I know that once I write final ArrayList list = new ArrayList(); I can add, delete objects from this list, but I can not list = new ArrayList() or list = list1. But what will be the use of declaring arraylist as
Private static final ArrayList list = new ArrayList();. And apart from the difference I have mentioned above what will be the difference between following two declaration:
1. ArrayList list = new ArrayList()
2. private static final ArrayList list = new ArrayList();
Just to "bring a little water to your Mill" you will understand the interest of final when you'll want to make your list publically availiable but unmodifiable.
In java one can make a list unmodifiable with Collections.unmodifiableList(modifiableList).
Now have a look to the following code :
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = tmp;
}
}
Well, in anyclass, anywhere in your code you can do something like this
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
When you add the final keyword to your variable, the first two won't be allowed
public static final List<String> MY_PUBLIC_LIST;
But you'll still be able to modify the content of the list :
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
By adding a Collections.unmodifiableList(modifiableList) at the end of the static block you'll prevent this too :
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
Ok we are almost there. Just to be sure you get the whole picture lets keep the Collections.unmodifiableList(modifiableList) but let me remove the final modifier
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
}
}
What can you do in that case ?
...
...
Well you can do whatever you want like in the first case (given that you assign the new list first) :
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
You're right that declaring the list final means that you cannot reassign the list variable to another object.
The other question (I think) was
public class SomeClass {
private static final ArrayList list = new ArrayList();
}
vs
public class SomeClass {
ArrayList list = new ArrayList();
}
let's take each modifier in turn.
private Means only this class (SomeClass) can access list
static Means that there is only one instance of the list variable for all instances of SomeClass to share. The list instance is associated with the SomeClass class rather than each new SomeClass instance. If a variable is non-static it's said to be an instance variable
final as you know means that you cannot reassign the list variable another value.
In the second declaration there are no modifiers, so the variable is an instance variable and it also gets package-private access protection (Sometimes called default access protection). This means that this class (SomeClass) and other classes in the same package can access the variable.
You can find out more about public, private, and package-private here: Access control
You can find out more about final and static here: Class variables
When you say
final ArrayList list = new ArrayList();
this means that the variable list will always point to the same ArrayList object. There are two situations in which this can be useful.
You want to make sure that no-one reassigns your list variable once it has received its value. This can reduce complexity and helps in understanding the semantics of your class/method. In this case you are usually better off by using good naming conventions and reducing method length (the class/method is already too complex to be easily understood).
When using inner classes you need to declare variables as final in an enclosing scope so that you can access them in the inner class. This way, Java can copy your final variable into the inner class object (it will never change its value) and the inner class object does not need to worry what happens to the outer class object while the inner class object is alive and needs to access the value of that variable.
The second part of your question is about the difference between
ArrayList list = new ArrayList();
and
private static final ArrayList list = new ArrayList();
The difference of course are the modifiers. private means not visible outside the class, static means that it is defined on the class level and doesn't need an instance to exist, and final is discussed above. No modifiers means package-private or default access.
You say "I can add, delete (and find) objects", but who is I?
The different between your two cases concerns from which code those list operations can be called.
In general you need to consider the scope of the declaration, you greatly increase the maintainability of code if you reduce the visibility of your variables. If you have a class:
Public Class MyThing {
public int importantValue;
// more code
}
That important value can be changed by any other code, anywhere else in an application. If instead you make it private and provide a read accessor:
Public Class MyThing {
private int importantValue;
public int getImportantValue(){
return importantValue;
}
// more code
}
you now know only the class itself can change the value - for large applications this massively increases maintainability. So declaring the list private limits what code can see, and change the contents of the list.
The use of static makes the list shared by all instances of the class, rather than each instance getting its ovn copy.

Categories

Resources