Just curious about how jaxb works, I have a class annotated as follows:
#XmlRootElement(name = "MyJaxb")
Class MyJaxb
{
#XmlElement
protected String str;
public void setStr(String str)
{
this.str = str;
}
}
The access modifier of field str is protected, why Jaxb can still marshall and unmarshall it?
It uses reflection. A protected or private field or method can be accessed using the reflection API (using setAccessible(true) on the appropriate Field or Method object).
Remember - public, protected and private are controls on default visibility, nothing more. They do not (and cannot) prevent access using reflection.
Beyond answer that reflection can by-pass checks (which is correct), this is also something that other JDK internal parts need, specifically default Object serialization and deserialization. In general this is allowed because many tools benefit from such access. And like others have correctly pointed out, access rights are not meant as real security barriers. They are there to help programmers design abstractions properly, make it easier to come up with good designs.
Related
There are many questions and answers about using public fields in Object Oriented Programming, and most of them recommend not to use public fields for many reasons.
But when I looked into Android's code I found some classes are using public fields. For example Android.view.View has public fields mCachingFailed and mAttributes.
Why are they public? It is hard to think this is a mistake on Google and AOSP's part.
It isn't inherently a mistake to have public fields. It is not, as the bounty note suggests, an "OOP-fundamental-violation". After all these two classes are (for most purposes) identical:
public class DemoA {
public int field;
}
public class DemoB {
private int field;
public int getField() { return field; }
public void setField(int value) { field = value; }
}
That is to say, if you intend for callers to have direct read and write access to a field adding a getter and setter may just be extra boiler-plate.
The benefit of getters and setters, even if they do no other work than reading and writing to fields, is that they abstract the fact that the data is stored in a field at all. It could be stored in an external data source, or computed on the fly, or whatever you'd like, and callers don't have to worry about how the behavior is implemented. This is definitely a good practice in general because it separates the callers concerns (the API) from your concerns (the implementation).
However sometimes it's just overkill, and it's perfectly reasonable to expose public fields if that's the best way to provide the behavior your callers need. Most often, this is done for value types, classes that exist solely to group a number of fields together. There's little benefit to writing out scores of getters and setters when everything you need a class to do can be accomplished by simply making the fields public.
As a practical matter, Android has an additional concern. Method calls are expensive and the number of methods an app can (easily) define is limited to ~65k. For cases where it's safe to do so, exposing a field directly reduces the method overhead by two and saves valuable CPU time. That might not seem like a lot, but it adds up quickly.
Check out this section from developer.android.com:
In native languages like C++ it's common practice to use getters (i =
getCount()) instead of accessing the field directly (i = mCount). This
is an excellent habit for C++ and is often practiced in other object
oriented languages like C# and Java, because the compiler can usually
inline the access, and if you need to restrict or debug field access
you can add the code at any time.
However, this is a bad idea on Android. Virtual method calls are
expensive, much more so than instance field lookups. It's reasonable
to follow common object-oriented programming practices and have
getters and setters in the public interface, but within a class you
should always access fields directly.
Without a JIT, direct field access is about 3x faster than invoking a
trivial getter. With the JIT (where direct field access is as cheap as
accessing a local), direct field access is about 7x faster than
invoking a trivial getter.
Note that if you're using ProGuard, you can have the best of both
worlds because ProGuard can inline accessors for you
http://developer.android.com/training/articles/perf-tips.html#GettersSetters
Most likely, this is the reason you see public fields in AOSP.
I have a class that has many settable/gettable attributes. I'd like to use reflection to set these attributes, but I have 2 questions about my implementation
Here is some stripped down code from my class
class Q {
public String question_1;
public String question_2;
public String question_3;
public String answer_1;
public String answer_2;
public String answer_3;
//etc. etc. Many String attributes
// … constructor and other stuff are omitted
// here is my method for "dynamically" setting each attribute
public void set_attribute(String a_raw_string, String my_field) {
try {
Class cls = Class.forName("com.xyz.models.Q");
Field fld = cls.getField(my_field);
fld.set(this, a_raw_string);
}
catch (Throwable e) {
System.err.println(e);
}
}
I then set various fields like this:
Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.
This works (i.e., the instance variables are set when I call set_attribute.
However, they only work when the instance variables are declared public. When they are declared private I get a NoSuchFieldException
QUESTION 1: Why do I get that error when the fields are private? My naive assumption is that since the set_attribute function is part of the class, it should have unfettered access to the instance variables.
QUESTION 2: I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way). Is there a more recommended approach?
The reason that I want to use reflection is because it's a pain in the ass to declare a ton of setter methods…so I'm wondering if someone has solved this annoyance in a better way.
Thanks!
I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way)
Yep. Reflection is fairly slow and should only be used as a last resort. If this is simply to avoid having so much redundant code, consider using automatic code generation. For pure data objects, I would strongly recommend using protocol buffers; it will generate the getters / setters (you only need to declare the fields). Plus it allows for easy communication of the data between C++, Java, and Python.
If you have a class that has a lot of fields but isn't a pure data object... well
You should consider whether all the fields should be mutable. (Do you really need setters?)
Whether the fields should even be visible. (Do you need any accessors at all?)
It is often a good idea to make fields "final", initialize them in the constructor(s), and provide no access or provide limited access through an implemented interface.
Using setter methods is the accepted way to set values for class member variables, reflection should definitely not be used for that as the code will be harder to understand and run much more slowly.
Most IDEs (eg Eclipse or NetBeans) include tools for automatically creating getter and setter methods for a class's fields.
When they are private you need to call fld.setAccessible(true);
Yes, why don't you just set the fields directly and avoid reflection? It doesn't look like you're doing anything dynamic. It's just that they are private -- why? Perhaps you mean to expose getters/setters and make the fields private? If so, then you should just invoke the public setters.
I want to force future users of a class to access a private member also from future code written in that class only through an accessor method (even through junit or anything like that).
is there a way to do it in java? can someone show an example if possible?
You cannot force to do that, but you can create a method and document that enforcement in the javadoc.
private int myMember;
/**
* ATTENTION: use this method instead of setting the member directly.
*/
public void setMyMember(int value) {
this.myMember = value;
}
Also, there is an alternative solution which might work. Use ThreadLocal, like this:
private final ThreadLocal<String> member = new ThreadLocal<String>();
public void setMember(final String value) {
member.set(value);
}
The member field is final and cannot be changed. Therefore, clients will be forced to call the setter directly.
As long as the field is part of the class, anyone can access it directly. This can be a problem when we try to force all (co-)authors to go through the getters/setters because those method do some conversion, checking or bookkeeping stuff. Like incrementing internal counters.
A general solution, that comes to mind: it could be possible by using annotations. You'd have to create an annotation (and the annotation processor code) to ensure, that it is a compile time error if the field is used outside of it's getter/setter method:
#GetterSetterAccessOnly
private int value;
If you want to prevent reflection you can use a SecurityManager. If this is not an option you can get the call stack with Thread.currentThread().getStackTrace() and check the caller is from your class.
Two problems with this are; the performance won't be great. Anything you can do in the method you can do externally so the simplest work around is to copy its contents without the check. ;)
I suggest you document your reason for not allowing access this way.
Make use of inheritance to hide the field:
Do your class with all the fields and getter/setters that you need. (You may make it abstract)
Do a child class, that inherits from the previews one, and since the field isn't accessible, you force the use of the getter/setter pair.
As you are talking about the accessing in the same class, they have all the freedom to access the private member directly as well as through accessor method if that member has. So basically you cannot prevent them using the member directly in the same class.
I am afraid there is no standard way to do that. If a user has access to a class instance, although a private member is declared private, permissions can be changed at runtime and accessed anyway.
You need a classloader that enforces permissions. You can make an OSGi Bundle and enforce a control policy over the instance of your objects exported as services through interfaces. However this will tie you to an OSGi container to run your application.
Well, if they have access to your code, they can do anything they want. In the worst case, they remove your getters and setters and just put in a public field instead ;)
But of course you can motivate them to not access the variable directly with an according design:
you should check whether the others should rather implement subclasses instead of changing the class itself. Then private fields are, of course, only accessed via setters and getters.
you could move the data into a different class, and use your getters and setters to access the data in the other class. Doing this just for the sake of not having the data directly in your class is maybe a bit counter-intuitive, but since you probably have a good reason why they shouldn't access that very data, it indicates a different responsibility. So refactoring to meet the SRP is a good idea anyways.
I have a class that has many settable/gettable attributes. I'd like to use reflection to set these attributes, but I have 2 questions about my implementation
Here is some stripped down code from my class
class Q {
public String question_1;
public String question_2;
public String question_3;
public String answer_1;
public String answer_2;
public String answer_3;
//etc. etc. Many String attributes
// … constructor and other stuff are omitted
// here is my method for "dynamically" setting each attribute
public void set_attribute(String a_raw_string, String my_field) {
try {
Class cls = Class.forName("com.xyz.models.Q");
Field fld = cls.getField(my_field);
fld.set(this, a_raw_string);
}
catch (Throwable e) {
System.err.println(e);
}
}
I then set various fields like this:
Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.
This works (i.e., the instance variables are set when I call set_attribute.
However, they only work when the instance variables are declared public. When they are declared private I get a NoSuchFieldException
QUESTION 1: Why do I get that error when the fields are private? My naive assumption is that since the set_attribute function is part of the class, it should have unfettered access to the instance variables.
QUESTION 2: I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way). Is there a more recommended approach?
The reason that I want to use reflection is because it's a pain in the ass to declare a ton of setter methods…so I'm wondering if someone has solved this annoyance in a better way.
Thanks!
I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way)
Yep. Reflection is fairly slow and should only be used as a last resort. If this is simply to avoid having so much redundant code, consider using automatic code generation. For pure data objects, I would strongly recommend using protocol buffers; it will generate the getters / setters (you only need to declare the fields). Plus it allows for easy communication of the data between C++, Java, and Python.
If you have a class that has a lot of fields but isn't a pure data object... well
You should consider whether all the fields should be mutable. (Do you really need setters?)
Whether the fields should even be visible. (Do you need any accessors at all?)
It is often a good idea to make fields "final", initialize them in the constructor(s), and provide no access or provide limited access through an implemented interface.
Using setter methods is the accepted way to set values for class member variables, reflection should definitely not be used for that as the code will be harder to understand and run much more slowly.
Most IDEs (eg Eclipse or NetBeans) include tools for automatically creating getter and setter methods for a class's fields.
When they are private you need to call fld.setAccessible(true);
Yes, why don't you just set the fields directly and avoid reflection? It doesn't look like you're doing anything dynamic. It's just that they are private -- why? Perhaps you mean to expose getters/setters and make the fields private? If so, then you should just invoke the public setters.
Is there a way to exclude primitive and Object properties within Serializable Object from GWT Serialization?
public class Provider implements Serializable{
public Provider() {
}
//Id like to exclude this property:
private String password;
//
private String address1;
private String address2;
private String companyName;
private String phone;
}
I was hoping for something like
special annotation
I think what you are looking for is #GwtTransient
#GwtTransient, an annotation that
tells GWT RPC to treat a field as if
it were marked with the Java transient
keyword, even though it's not.
This annotation means the same thing
as the transient keyword,
but it is ignored by all serialization
systems other than GWT's. Usually the
transient keyword should be used in
preference to this annotation.
However, for types used with multiple
serialization systems, it can be
useful.
Reference: #GwtTransient
Can't you just declare it transient?
transient private String password;
If you really want to avoid using the transient keyword, you might want to look into Custom Field Serializers.
On my last GWT project, I used them to serialize immutable classes, since GWT-RPC had limitations for those.
It's a poorly documented feature, and the best explanation I found at the time was not in the GWT documentation, but on this great wogwt wiki page. You may also find some examples in GWT's com.google.gwt.user.client.rpc.core package, since GWT uses a lot of those.
Please note that CustomFieldSerializers still have some issues, such as issue 2931 and issue 3315. Also, I don't like the way they are defined: instead of using static methods, it would have been better to let users implement a CustomFieldSerializer<T> interface. We would have gained type safety and inheritance. But this is a whole other debate, and the GWT compiler might actually mandate the use of those static methods for performance reasons (I haven't looked into it).
Still, it works, and it's good to have them in specific cases.
add transient to the field