See this table:
Access Levels
Modifier | Class | Package | Subclass | World
-------------+--------+-----------+-----------+--------
public | Y | Y | Y | Y
protected | Y | Y | Y | N
no modifier | Y | Y | N | N
private | Y ← | N | N | N
Answer from Maroun on Stack OverflowSee this table:
Access Levels
Modifier | Class | Package | Subclass | World
-------------+--------+-----------+-----------+--------
public | Y | Y | Y | Y
protected | Y | Y | Y | N
no modifier | Y | Y | N | N
private | Y ← | N | N | N
Access modifiers describe access for classes, not instances. Since value was declared in String class, all its members - like constructors - have unlimited access to it.
You can access those values, and manipulate them via Reflection. By this mechanism you can check fields and invoke methods.
Using java.lang.reflect.Member.setAccessible(true) will override any privacy at runtime (not that there is much – the JVM will happily access private fields or methods given their name, see this answer.
java - Accessing fields of dependency without getters or reflection - Stack Overflow
java - Why is it possible to access a field without a getter? - Stack Overflow
java - Access private property without get/set - Stack Overflow
Java class: Why do you make fields private?
Videos
You're just using field access. Having a getSet() method would make no difference, as the Java compiler won't use an accessor method automatically for you.
I suspect what you're missing is that private access isn't determined by the object whose member you're trying to access - the code in Cage has access to the private members of any other Cage, including the set field.
Section 6.6 of the Java Language Specification describes access control, including:
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.
The syntax
cage.set
is simply accessing the field set within your object cage. The field is declared private but you are still inside the same class Cage.
you can access them, by using reflection,
Test test = new Test()
Field field = test.getClass().getDeclaredField("x");
field.setAccessible(true);
System.out.println(field.getName() + "="+field.get(test ));
but, you shouldn't do this
You can't.
That's why we talk in "encapsulation". Only if you change or modify from private to something else or if you use reflection (what would make it even more complicated).
I don't see any problem in using the famous getters and setters.
If I were to make public getters and setters to access those private fields of a class, why not just make those fields public from the beginning? If I make them public from the beginning, I don't have to have getters and setters and make the code simple, right?
In order to access private fields, you need to get them from the class's declared fields and then make them accessible:
Field f = obj.getClass().getDeclaredField("stuffIWant"); //NoSuchFieldException
f.setAccessible(true);
Hashtable iWantThis = (Hashtable) f.get(obj); //IllegalAccessException
EDIT: as has been commented by aperkins, both accessing the field, setting it as accessible and retrieving the value can throw Exceptions, although the only checked exceptions you need to be mindful of are commented above.
The NoSuchFieldException would be thrown if you asked for a field by a name which did not correspond to a declared field.
obj.getClass().getDeclaredField("misspelled"); //will throw NoSuchFieldException
The IllegalAccessException would be thrown if the field was not accessible (for example, if it is private and has not been made accessible via missing out the f.setAccessible(true) line.
The RuntimeExceptions which may be thrown are either SecurityExceptions (if the JVM's SecurityManager will not allow you to change a field's accessibility), or IllegalArgumentExceptions, if you try and access the field on an object not of the field's class's type:
f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type
Try FieldUtils from Apache commons-lang3:
FieldUtils.readField(object, fieldName, true);
P.S. In my opinion, reflection is evil.
Referring to the official JPA specification (final version, JPA 2.1) in Section 2.2 (page 24) we find:
The persistent state of an entity is accessed by the persistence provider runtime either via JavaBeans style property accessors (“property access”) or via instance variables (“field access”). Whether persistent properties or persistent fields or a combination of the two is used for the provider’s access to a given class or entity hierarchy is determined as described in Section 2.3, “Access Type”.
In Section 2.3.1 (page 27) this definition is made more concrete - with respect to your question:
By default, a single access type (field or property access) applies to an entity hierarchy. The default access type of an entity hierarchy is determined by the placement of mapping annotations on the attributes of the entity classes and mapped superclasses of the entity hierarchy that do not explicitly specify an access type. [...]
• When field-based access is used, the object/relational mapping annotations for the entity class annotate the instance variables, and the persistence provider runtime accesses instance variables directly. All non-transient instance variables that are not annotated with the Transient annotation are persistent.
• When property-based access is used, the object/relational mapping annotations for the entity class annotate the getter property accessors, and the persistence provider runtime accesses persistent state via the property accessor methods. All properties not annotated with the
Transientannotation are persistent.
The term directly refers to an access strategy which allows the manipulation of an object's field (value) without the need to use getter/setter methods. In Java and for most OR-mappers (at least the ones I know of) this is achieved via Introspection - using the Java Reflection API. This way, classes' fields can be inspected for and manipulated to hold/represent data values from the (relational) database entries (i.e., their respective columns).
For instance, the provider Hibernate gives the following explanation in their User Guide:
2.5.9. Access strategies
As a JPA provider, Hibernate can introspect both the entity attributes (instance fields) or the accessors (instance properties). By default, the placement of the @Id annotation gives the default access strategy.
Important note:
Be careful when experimenting with different access strategies! The following requirement must hold (JPA specification, p. 28):
All such classes in the entity hierarchy whose access type is defaulted in this way must be consistent in their placement of annotations on either fields or properties, such that a single, consistent default access type applies within the hierarchy.
Hope it helps.
The provider can use reflection to access a private field on a class instance.
That is the whole point of private fields; they are not accessible outside the scope of the enclosing class.
You got the following options:
- Change that class to provide a getter
- Change your overall design, to either not need that value; or find another way to make it available to both classes
- Not recommended: use reflection and its ability to override the "private" protection at run time
The best decision is to have a getter. It's the safest and cleanest solution when it comes to programming best practices.
It's possible to achieve what you want using reflection - you can find the field by name (what if the name changes in a future version of the class?) and the extract it's value like this:
A a = new A(5);
Field field = A.getField("a");
field.setAccessible(true);
int value = field.get(a);
But bear in mind that this is considered super hacky and it strongly advice against.
Access modifiers work on class level not on object level.
You are allowed to access k.i since the code lies within the same class as in which the member i is declared.
The rationale is (afaik) the following: You encapsulate the data (partly) in order to ease future maintenance and refactorings. When you refactor code, you refactor classes, not objects.
Your main method is part of the Fish class isn't it?
The following doesn't work:
public class Fish {
private int i = 1;
}
class Reptile{
public static void main(String[] args) {
Fish k = new Fish();
k.i = 2; // Compiler error.
}
}
It is possible using reflection, see this link for a good explanation of how. How do I read a private field in Java?
That said, you really really need to have an extremely good reason for doing so, because if you don't control the code chances are that sometime down the road the owner of that code makes a change and everything breaks at runtime. And if you own the code there is no reason to do it in the first place.
If you control the code or have access to the owner, do the right thing and implement proper access methods to get the data you need.
You can't, unless you use reflection (more about that below).
If the member is declared private, then other classes aren't allowed to read it. That's what private scope is about.
If you can modify the class that owns the ArrayList, you can add a getter. It is better not to get the ArrayList in it's entirety (it's a reference and you might inadvertently change it). Add a getter that gets one element, instead.
There is also the option to use reflection, but as is mentioned several times on this page, this is strongly discouraged. Reflection is a technology that allows code to inspect other code in the same system. Should you really want to use it, the tutorial is here.