I have got a list of constants in a class like:
public class constants{
public String avg_label ="......";
public String count_label="......";
}
While calling , is it possible to do something like this:
public class MapDialogue{
Constants c1 = new Constants();
public String mappingLabels(String node){
String text = "c1."+node+"_label";
//Is there someway of parsing this text as code
//like in unix shell scripting?
}
}
Yes, you could use Reflection. And the code would look something like this:
String value = (String)Constants.class.getDeclaredField(node).get(c1);
Although, I am kind of unsure about a couple of things:
Why are the constants in your class not really constants? (Constants are supposed to be static and final)
Why are you even instantiating your Constants class? You should be accessing them like Constants.FIELD_NAME.
You might want to take assylias's advice in the first comment and try to avoid using reflection at all times, surely there are other ways that you could do it that are less costly.
I suppose in your case, you would most likely be better of using some sort of Map
Yes, there is a way to achieve that. You can do so via the Reflection package in the Field API. The Java tutorials for this can be located here.
The basic idea is:
Field yourField = c1.getClass().getDeclaredField(yourString);
As a side note, a Constants file usually has its members as public static final. With those modifiers, you won't need to create an instance of Constants, and the values will also be unmodifiable.
Related
public class ConstructorA {
private String FieldA, FieldB, FieldC;
public String Setter(String ArgAA, String ArgAB) {
this.ArgAA = ArgAB; //or ArgAA could include "this."
}
public String Getter(String ArgBA) {
return ArgBA;
}
ObjectA = new ConstructorA();
ObjectA.Setter(FieldA, "TextA");
ObjectA.Setter(FieldB, "TextB");
ObjectA.Setter(FieldC, "TextC");
System.out.printf("%s %s %s", ObjectA.Getter(FieldA), ObjectA.Getter(FieldB), ObjectA.Getter(FieldC));
I'm trying to create generic setter and getter (mutator and accessor) methods that would be able to assign and retrieve values to and from fields without a specific pair of such methods for each individual field, by passing the name of the field as an argument into the method pair. This is partly due to curiosity, but also to reduce boilerplate code for cases where objects have a lot of fields, each with its own getter/setter. The code I'm making has been abstracted in the above snippet to show what exactly I wish to accomplish. If any extra detail or clarification is needed or anything seems ambiguous, please don't hesitate to ask.
I understand the code above is rather ridiculous and likely resembles pseudocode more than java, since the above would not work at all, I think. But is anything remotely similar to the above possible? I'm new to Java and so not very familiar with its features and limitations. I understand something similar would be possible in C, using pointers?
Anyhow, sorry for the lengthy text, and thanks in advance! Any input is valuable and much appreciated.
Don't do this.
If a class has many getters, it is badly designed.
You are essentially treating an object as a Map of names to values. Perhaps your use case is actually that you need a Map from names to values?
I also agree with #Raedwald that too many fields can suggest a possibly design deficiency. That said, there are easier alternatives to reducing code rather than accessing fields via reflection as your post suggests.
One alternative is to add a library like Lombok, which inject code during compile time if special annotations are applied to fields, classes, methods, etc.
For example the #lombok.Data annotation will create getters, setters, toString, constructors, hashcode and equals automatically for you. eg
#lombok.Data
public class LargePojo {
private String a;
private int b;
private List<String> c;
}
You can then access the field a like this:
largePojo.getA()
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.
So I am writing a program right now and am conflicted about how I should program it. I have two options:
public class Translator {
private Translator(){}; //prevents instantation
/****
***Stuff
***/
public static String translate(String oldLanguage, String newLanguage, String text){
//METHOD Code
}
}
or
public class Translator {
private String oldLanguage;
private String newLanguage;
public Translator(String oldLanguage, String newLanguage){
this.oldLanguage = oldLanguage;
this.newLanguage = newLanguage;
};
/****
***Stuff
***/
public String translate(String text){
//METHOD Code
}
}
Which should I use and why? This will be the API end of my program.
Also, as programmer which do you find more convenient when dealing with APIs and why?
I would prefer to use the stateless version of translator, but I would prefer a state-full version of translated. The reason is, if you get rid of state then you can often get rid of an entire class of synchronization bugs while moving some of the important information closer to where it is actually used. Imagine, for example, if the two language variables were part of a 1000 line class. Would you want to look up how they are set every time they are used?
The reason I like state for translated is whereas a general translator can exist without knowing what languages it is going to be used for, if you lose what languages are used in a translated, you don't know as well what to do with it anymore (similar to losing your units in a math problem).
For the stateful option, a version I like better is, instead of:
...
private String oldLanguage;
private String newLanguage;
use:
...
private final String oldLanguage;
private final String newLanguage;
... and instead of something like:
myTranslator.setLanguages("spanish", "english")
Translated myTranslated = myTranslator.translate(original)
you can use:
Translator spanishEnglish = new Translator("spanish", "english")
Translated myTranslated = spanishEnglish.translate(original)
That's quite an interesting question, which doesn't have a single best answer. The criteria to choose, out of the top of my head, are mainly:
do you intend to instantiate a translator and reuse it several times with the same old and new languages?
does your translator need to keep some state in memory to be able to translate, without having to reload this state every time a translation is needed?
does your translator have other methods that also use the old and new languages?
is there somewhere in the application where the translator would have to be called without even caring/knowing about what the old and new language are, taking a pre-configured translator as argument?
do you need to be able to mock a translator and inject it in various other components of your code to unit-test them?
If the answers to these questions are yes, then a stateful translator (i.e. your second option) should be used. If the answers are no, then you could go with the first option.
As per the Object Oriented Programming standard, class is a representation of an entity. So you should define something as an attribute of class only if those are the properties of the entity represented by class. Having said that, add oldLanguage and newLanguage to your Translator class only if Translator entity has these attributes.
I would prefer to use the first one
public class Translator {
private Translator(){}; //prevents instantation
/****
***Stuff
***/
public static String translate(String oldLanguage, String newLanguage, String text){
//METHOD Code
}
}
why ?
the answer why should I instantiate an object to translate some thing if I can just do it directly .
Translator.translate(S,S,S);
A method of a class can (should?) be static when it does not access any non-static members or methods of this class.
Now this leads us to the question, when a member (field) of a class should be static or not:
A member (field) of a class must be non-static if it is relevant for defining the state of an instance (= object) of this very class.
So in summary, if something is relevant for the state of an object, then make it instance data, if not (only relevant for the calculation), then pass it as parameter into the method.
In addition to that, it becomes now clear, that it only makes sense to create an instance of a class, if you wish to represent a state. If zero non-static members exist, then you don't need to be able to create an instance of your class.
I theoretically understand the point why there is no abstract static in Java, as explained for instance in Why can't static methods be abstract in Java .
But how do I solve such a problem then?
My application uses files of a few types, which I want to assign static properties like a description of that file type (like "data file", the other being "config file", etc.).
Obviously, I would put that into a static String so that the description is accessible without instancing a file (useful for the GUI f.i.).
On the other hand, obviously all file types should have some common methods like getStatus(), which obviously I want to inherit from a common superclass MyFileType.
getDescription() would of course be abstract in the superclass.
Tried using a combination of a superclass and an interface, but similar problem: A static implementation of an abstract method is not allowed.
How would a Java guru solve this?
Is it really such a bad implementation that I want to create?
Many thanks,
Philipp
To restate the problem: you want your per-file-type classes to have statically available information on the type (e.g., name and description).
We can easily get part-way there: create a separate class for your type info, and have a static instance of this (appropriately instantiated) in each per-file-type class.
package myFileAPI;
public class TypeInfo {
public final String name;
public final String description;
public TypeInfo(String name, String description) {
this.name = name;
this.description = description;
}
}
and, say:
package myFileAPI;
public class TextFile {
public static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
}
Then you can do stuff like:
System.out.println(TextFile.typeInfo.name);
(Of course, you could also use getters in TypeInfo to encapsulate the underlying strings.)
However, as you said, what we really want is to enforce the existence of a particular signature static method in all your per-file-type classes at compile time, but the 'obvious' design path leads to requiring an abstract static method in a common superclass which isn't allowed.
We can enforce this at run-time though, which may be good enough to ensure it is coded correctly. We introduce a File superclass:
package myFileAPI;
public abstract class File {
public static TypeInfo getTypeInfo() {
throw new IllegalStateException(
"Type info hasn't been set up in the subclass");
}
}
If TextFile now extends File, we will get this exception when calling TextFile.getTypeInfo() at runtime, unless TextFile has a same-signature method.
This is quite subtle: code with TextFile.getTypeInfo() in still compiles, even when there is no such method in TextFile. Even though static methods are bound at compile time, the compiler can still look through the class hierarchy to determine the compile-time static call target.
So, we need code like:
package myFileAPI;
public class TextFile extends File {
private static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
// Shadow the superclass static method
public static TypeInfo getTypeInfo() {
return typeInfo;
}
}
Note that we are still shadowing the superclass method, and so File.getTypeInfo() can still be 'meaninglessly' called.
This sounds like a great time to pull out the Fundamental Theorem of Software Engineering:
Any problem can be solved by adding another layer of indirection.
The problem you have right here is that a file carries around multiple pieces of information - what the type of the file is, a description of the file, the file contents, etc. I'd suggest splitting this into two classes - one class representing a concrete file on disk and its contents, and a second that is an abstract description of some file type. This would allow you to treat the file type class polymorphically. For example:
public interface FileType {
String getExtension();
String getDescription();
/* ... etc. ... */
}
Now, you can make subclasses for each of the file types you use:
public class TextFileType implements FileType {
public String getExtension() {
return ".txt";
}
public String getDescription() {
return "A plain ol' text file.";
}
/* ... */
}
You can then have some large repository of these sorts of objects, which would allow you to query their properties without having an open file of that type. You could also associate a type with each actual file you use by just having it store a FileType reference.
annotations could be fine for your purpose.
#FileProperties(desc="data file")
public class DataFile extends XFile { ... }
FileProperties props = DataFile.class.getAnnotation(FileProperties.class);
String desc = props.desc();
Accessing the info still requires reflection, however it's a little better than using static field/method.
Java compiler does not enforce that all subclasses are annotated as such. You can add your logic to the compiler (using annotation processing) but that's too complicated. It's ok to check it at runtime.
Update:
This is also possible:
#FileInfoClass ( DataFileInfo.class )
#public class DataFile
The question is not clear enough to provide an objective answer. Since I cannot give you a fish, this answer is more on the lines of "Teach you to fish" :)
When faced with design issues like these, where you think "duh..now sure why such a simple thing is so hard" more often than not, you are either designing it just incorrectly, or you are overcomplicating things. If I am empathizing correctly, your design issue seems like a "common requirement" yet the language is not allowing for any elegant solutions.
Trace back your design steps/decisions
question all the "obvious" and "of course" you are basing your design on (you are using quite a few above)
see if things can be simplified (don't take any of the OO concepts to their logical extreme. Make compromises based on ROI)
...and you will most likely arrive at an acceptable answer.
If you still don't, post back the classes and interfaces you think you want (with compile errors since language is not allowing certain things), and maybe we can help you tune your design.
I basically had the exact same problem.
You may want to look at the
solutions suggested to me in my question
I liked Bozho's idea, but according to himself it was a bad idea. :) I suppose better programmers can explain why it is so. Ralph's and Jon Skeet's solution also works.
Sounds like you need to use a singleton. Basically, you call a static method like MyFileTypes.getDataFileInstance() which creates a single instance (or reuses if already created) of an object and when you first create it setup the 'constants' as needed. I'll see if I can find you a good example but your post isn't very clear about how you want to use it.
You could create a FileMetadata class that has all the info you need. When your app starts up, you could create instances of FileMetadata, and keep static pointers to them so you can access them from anywhere in the JVM.
This way you put the abstract stuff in the actual instances; anything the stuff that does not call for abstract semantics can be static...
I don't know how a java guru would solve it, but I'd probably create a resource bundle with all the descriptions in a properties file like this:
com.bigcompany.smallapp.files.DataFile=Data file
com.bigcompany.smallapp.files.ConfigFile=Config file
Handling the bundle can conveniently be placed in the superclass or elsewhere.
Another option is to use reflection to access the static fields in each subclass, but then you need to make sure that all the subclasses have a static field with the same name.
There could be other options too, even refactoring the code so that the subtypes aren't represented by a separate class each, but in general there's no watertight solution.
Instead of putting your static properties actually in static properties, put a reference to MyFileTypeDescription as a static property.
i.e.
class MyFileType {
static MyFileTypeDescription description;
...
<your regular attributes>
}
abstract class MyFileTypeDescription {
String name;
abstract String getDescription();
}
Something along this way, if I understood your problem correctly.
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.