Private members in Enum Java [duplicate] - java

This question already has answers here:
Why can outer Java classes access inner class private members?
(10 answers)
Closed 9 years ago.
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.i); // private
}
}
output: 1
Why 1 is shown if it a private member in enum?

Outer classes have full access to the member variables of their inner classes, therefore
i is visible in the Test class.
In contrast, if MyEnum was external to the Test class, the compiler would complain about the visibility of i,

It's (i) a member field being referenced within the same class (MyEnum); no access modifier prevents that - the private access modifier defined on i will prevent it's visibility outside this class.
Suggested Reading

private access from a containing type to a nested type is permitted, see Why are private fields on an enum type visible to the containing class?

vlaueA is considered a static variable so you can call it within MyEnum since i in the
same enum whice play the same as a class so MyEnum can access valueA which can access i

Outer class will have the access to inner class member even if it is private because you have defined main method inside the outer class.

Related

Volatile variable visibility to inner class [duplicate]

I have a class which has another static inner class:
class A {
private List<String> list;
public static class B {
// I want to update list here without making list as static
// I don't have an object for outer class
}
}
You generally use static classes when you don't need access to the instance variables. If you need to access the instance variables make the class non-static.
As you can see from other answers that you will need a non-static inner class to do that.
If you really cannot make your inner class non-static then you can add required getter and setter method in outer class and access them by creating an instance of outer class from inside inner static class:
public class A {
private List<String> list = new ArrayList<>();
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public static class B {
// i want to update list here without making list as static
void updList() {
A a = new A();
a.setList(someOtherList);
System.out.println(a.getList());
}
}
}
No, you'll need a non-static inner class to do that.
From the JLS §8.5.1:
The static keyword may modify the declaration of a member type C within the body of a non-inner class or interface T. Its effect is to declare that C is not an inner class. Just as a static method of T has no current instance of T in its body, C also has no current instance of T, nor does it have any lexically enclosing instances.
It is a compile-time error if a static class contains a usage of a non-static member of an enclosing class.
In your code, list is an instance variable of class A and B is nested static class. The rules of accessing static and not static member don't change for nested static class.
The variable list is instance variable so a can't be accessed from static context.
To enable this, you need to change static nester class to inner class.
class A {
private List<String> list = new ArrayList<String>();
public class B {
public void someMethod(){
list.add("abc");
}
}
}
private List<String> list;
Here list is an instance variable while the inner class is static which means that class B is the same across different class A instances; one cannot access it. And, that too for a very good and obvious reason.
One solution that you can use is pass reference of member list to the constructor of class B with a weakReference to avoid memory leak.
Something like this:
class A {
private List<String> list;
public static class B {
WeakReference<List<String>> innerList;
//constructor
B(WeakReference<List<String>> innerList){
this.innerList = innerList;
}
}

can we modify private variables in child class [duplicate]

This question already has answers here:
Accessing private instance variables of parent from child class?
(11 answers)
Closed 4 years ago.
can we modify a private variable through child class. We can use it by set and get methods but how can we modify them in child class.
You don't have a direct access to private members of parent class through child class. You can specify getters and setters with protected or public access modifier in parent class and change or read value of that private member of parent class by calling proper method - getter or setter.
Example of how you can achieve that:
class Parent {
private int member;
public void setMember(int member) { // setter
this.member = member;
}
public int getMember() { // getter
return member;
}
}
class Child extends Parent {}
public class TestClass {
public static void main(String[] args) throws IOException {
Child child = new Child();
System.out.println("member = " + child.getMember());
child.setMember(5);
System.out.println("member = " + child.getMember());
}
}
Output that you get:
member = 0
member = 5
No, you cannot modify private variables in a super class, unless you are using reflection.
The only way to access them would be getter and setter.
There is no way to change private from the other class.
You can change in the same class
class Parent {
private value;
public class Method {
System.out.println(value++);
}
}

Java: why a constructor has access modifier?

For example a class:
//class1
class A {
private A() { } // why would I make it private?
public A(int) { } //why isn't it implicitly public?
}
//class2
class B {
public static void main(String[] args) {
//A a = new A();
}
}
A constructor instantiates a class so why it has the access modifier?
Is there a case when we have to declare a constructor private?
A constructor instantiates a class so why it has the access modifier?
The modifier can be used so you control where the object can be constructed.
Is there a case when we have to declare a constructor private?
Say you have a factory method like
class A {
private A(int n) { }
public static A create(int n) {
return new A(n);
}
}
or you have a shared constructor which should be called directly.
class B {
public B(int n) {
this(n, "");
}
public B(String str) {
this(0, str);
}
private B(int n, String str) { }
}
or you have a Singleton
final class Singleton {
Singleton INSTANCE = new Singleton();
private Singleton() { }
}
however I prefer to use an enum which has a private constructor.
enum Singleton {
INSTANCE;
}
or you have a Utility class
final class Utils {
private Utils() { /* don't create one */ }
public static int method(int n) { }
}
however I prefer to use an enum in this case
enum Utils {
/* no instances */;
public static int method(int n) { }
}
Note: if you use a private constructor on a final class you can still create instances using nested classes, or reflection. If you use an enum you can't create an instance as easily/accidentally.
Warning: You can create instances of an enum using Unsafe
Note in enum the constructor has to be private
class BuySell {
BUY(+1), SELL(-1);
private BuySell(int dir) { }
}
You don't have to make it private explicitly as this is the default.
The private modifier when applied to a constructor works in much the same way as when applied to a normal method or even an instance variable. Defining a constructor with the private modifier says that only the native class (as in the class in which the private constructor is defined) is allowed to create an instance of the class, and no other caller is permitted to do so. There are two possible reasons why one would want to use a private constructor – the first is that you don’t want any objects of your class to be created at all, and the second is that you only want objects to be created internally – as in only created in your class.
Uses of private construtor:-
1) Private constructors can be used in the singleton design pattern
2) Private constructors can prevent creation of objects
This might also help Can a constructor in Java be private? the use cases of private constructor
Constructor are not responsible for Creating a object of a Class, these constructor are only responsible for initialize the member variables only.
There are various Reason behind this. One of the most popular reason behind this is design-Pattern.
//class1
class A {
private A() { } // why would I make it private?
}
why make private Constructor ?
If you want to make a Class singleton then your constructor must be private. then only it is possible to make a Class a Singleton.

How does java support instance variables of java enum constants?

I know that in Java an enum constant is implicitly static final variable. But the enum class can have an instance variable say size. So each enum constant will have a copy of 'size'.
What is the equivalent Java code for this? I mean it "seems" the static enum constant is using a non-static instance variable which is not possible normally?
enum Members{
A(1),B(2),C(3); // I have 3 enum constants here
private int size;
Members (int size) {
//System.out.println("Initializing var with size = "+size);
}
}
Equivalent code I know so far:
public final class Member extends Enums<Members> {
public static final Members A;
// ...
// What happened to size? How do A,B,C get a copy of size?
}
Edit : To restate my question-
I am interested in behind the scene implementation by compiler. I already know how to use enums. I am looking for what the compiler does? (so for example, if I simply write A, the compiler translates it to "public static final Member A". I want to know how compiler gives a copy of size to each A,B,C.
I mean it "seems" the static enum constant is using a non-static instance variable which is not possible normally?
It is absolutely possible: each static variable in the enum is an object in its own right, complete with its instance variables. The instance is static in the enum, but it does not make the context of the instance itself a static context.
public final class Member extends java.lang.Enums<Members> {
public static final Members A = new Member(1) {
public String toString() { return "A:"+size; }
};
public static final Members B = new Member(2) {
public String toString() { return "B:"+size; }
};
public static final Members C = new Member(3) {
public String toString() { return "C:"+size; }
};
private final int size;
protected Member(int size) { this.size = size; }
}
I mean it "seems" the static enum constant is using a non-static instance variable which is not possible normally?
What I meant by "normally" was that in non-enum classes a static variable can't access non static variables
It's still true: a static variable can't access non-static variables.
In your example code, you don't do this:
there is no static variable accessing non-static variables.
The constructor Members(int size) is not in a static context (a constructor never is).
A, B and C are all instances of the enum type Members,
and when these instances are created,
the constructor is called with the size parameter.
Once constructed, these objects will be treated as static constant values.
Perhaps another example can help:
class Person {
private final String name;
Person(String name) {
this.name = name;
}
}
class EmployeeDatabase {
private static final Person CEO = new Person("Jack");
}
Here EmployeeDatabase.CEO is a static constant object with a non-static field name.
This is just like Members.A, a static constant object with a non-static field size.
I want to know how compiler gives a copy of size to each A,B,C.
Exactly the same way as it passes constructor parameters to any object.
You can read all about enums in the docs.

java private access modifier can be accessed out side of the class?

Why java compiler is not restricting from accessing a private attribute from other class?
I have inner class which has a attribute 'a' with modifier 'private'. I can able to access this variable with its instance variable out side the class. see the code below.
package com.test;
public class Test {
public Test() {
}
public static void main(String[] args) {
new Test().execute(); // test method
}
public void execute() {
InnerClass innerClassInstance = new InnerClass();
// accessing private member from other class instance, HOW?
System.out.println(innerClassInstance.a);
InnerStaticClass innerStaticClassInstance = new InnerStaticClass();
// accessing private member from other class instance, HOW?
System.out.println(innerStaticClassInstance.a);
}
private final class InnerClass {
private int a; // accessible only in InnerClass??
}
private final static class InnerStaticClass {
private int a; // accessible only in InnerClass??
}
}
A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Sorry, I misread the question.
Looks at JLS http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-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.
So, a field in inner-class (which is obviously inside class body) can be accessed by outer class even if it's private.
See the Java language specification:
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.
your Inner class is a member of your Test class so, Test class can access private member of Inner class too.
Try like this it will give compile error
public class Test {
public Test() {
}
public static void main(String[] args) {
new Test().execute(); // test method
}
public void execute() {
InnerClass innerClassInstance = new InnerClass();
// accessing private member from other class instance, HOW?
System.out.println(innerClassInstance.a);
InnerStaticClass innerStaticClassInstance = new InnerStaticClass();
// accessing private member from other class instance, HOW?
System.out.println(innerStaticClassInstance.a);
}
}
class InnerClass {
private int a; // accessible only in InnerClass??
}
final class InnerStaticClass {
private int a; // accessible only in InnerClass??
}
These nested classes are meant for that .When you have private
members in a class ,we write nested class to do unit testing.

Categories