You can access those values, and manipulate them via Reflection. By this mechanism you can check fields and invoke methods.
Answer from T.G on Stack OverflowYou 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.
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
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.
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 class: Why do you make fields private?
java - Access private property without get/set - Stack Overflow
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.
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?
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.
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.
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.
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.
Four disadvantages that I can think of:
- If you want to have a read-only and mutable form of the same entity, a common pattern is to have an immutable class Entity that exposes only accessors with protected member variables, then create a MutableEntity which extends it and adds setters. Your version prevents it.
- The use of getters and setters adheres to the JavaBeans convention. If you want to use your class as a bean in property-based technologies, like JSTL or EL, you need to expose public getters.
- If you ever want to change the implementation to derive the values or look them up in the database, you'd have to refactor client code. An accessor/mutator approach allows you to only change the implementation.
- Least astonishment - when I see public instance variables, I immediately look for who may be mutating it and worry that I am opening pandora's box because encapsulation is lost. http://en.wikipedia.org/wiki/Principle_of_least_astonishment
That said, your version is definitely more concise. If this were a specialized class that is only used within a specific package (maybe package scope is a good idea here), then I may consider this for one-offs. But I would not expose major API's like this.
Get rid of the getters/setters too, and you're fine!
This is a highly controversial topic amongst Java programmers.
Anyways, there's two situtation where i use public variables instead (!) of getters/setters:
- public final To me this signals "I'm immutable" much better than just a getter. Most IDEs will indicate the final modifier with a 'F' during auto-completion. Unlike with getters/setters, where you have to search for the absence of a setXXX.
- public non-final I love this for data classes. I just expose all the fields publicly. No getters, setters, constructors. No nothing. Less than a pojo. To me this immediately signals "look, i'm dumb. i hold data, that's all. it's YOUR job to put the right data inside of me". Gson/JAXB/etc. handle these classes just fine. They're a bliss to write. There's no doubt about their purpose or capabilities. And most importantly: You know there are no side effects when you change a variable. IMHO this results in very concise data models with few ambiguities, whereas getters and setters have this huge problem where sometimes magic happens inside of them.