hello guys i'm not sure if the title is descriptive enough.what i mean is creating an enum
like so
public enum Test{
ONE, TWO ,THREE
}
this looks like hard coded.if for some reason i need to add the FOUR some certain business rules evolution reasons.should i code it and deploy it again?
isn't a way to let it pick the elements from a file , spring config for example or property file?
THanks for reading.
If the enum value doesn't explicitly exist in code, how could you ever use it? Test.Four would not compile. Any code which could somehow reference Test.Four would be invalid and would crash, until the point in time when the file is read and the new values are added.
You can, of course, use arrays or collections of values and manipulate those at runtime - load them from a file or from the database or whatever - but not enums.
I asked a similar question here. The content may be of interest.
The concensus seemed to be that Java's enum type is static by design. If you need something that can be altered at runtime, you should ideally use a different data structure.
The less preferred ideas were along the lines of extending Enum, etc.
You may store in a database table.
Related
I am currently taking a project management class and the professor gave this assignment to compare two .java files methods and fields in all cases programmatically. I don't think it's actually possible to do but maybe I am wrong!
The assignment spec is as following (its extremely ambiguous I know)
In this assignment, you are required to write a comparison tool for two
versions of a Java source file.
Your program takes as input two .java files representing those two versions
and reports the following atomic changes:
1. AM: Add a new method
2. DM: Delete a method
3. CM: Change the body of a method (note: you need to handle the case where a method is
relocated within the body of its class)
4. AF: Add a field
5. DF: Delete a field
6. CFI: Change the definition of an instance field initializer (including (i) adding an initialization to a
field, (ii) deleting an initialization of a field, (iii) making changes to the initialized value of a field,
and (iv) making changes to a field modifier, e.g., private to public)
So that's what I am working with and my approach was to use reflection as it allows you to do everything but detect differences in the method body.
I had considered the idea that you could create a parser but that seemed ridiculous, especially for a 3 credit undergrad class in project management. Tools like BeyondCompare don't list what methods or fields changed, just lines that are different so don't meet the requirements.
I turned in this assignment and pretty much the entire class failed it with the reason as "our code would not work for java files with external dependencies that are not given or with java files in different projects" - which is completely correct but also I'm thinking, impossible to do.
I am trying to nail down a concrete answer as to why this is not actually possible to do or learn something new about why this is possible so any insight would be great.
What you got wrong here is that you have started to examine the .class files (using reflection). Some of the information listed above is not even available at that stage (generics, in-lined functions). What you need to do is parsing the .java files as text. That is the only way to actually solve the problem. A very high-level solution could be writing a program that:
reads the files
constructs a specific object for each .java file containing all the informations that needs to be compared (name of the functions, name of the instance variables, etc)
compares the constructed objects (example: addedFunctions = functionsFromA.removeAll(functionsFromB)) to provide the requested results
Note: if this is an assignment, you should not be using solutions provided by anybody else, you need to do it on your own. Likely you will not get a single point if you use a library written by somebody else.
I have recently started learning java as my first ever step into object oriented programming and have been having trouble with having my objects interact properly, so I have a few questions, which seem to be incredibly simple but for some reason I cannot find the answers elsewhere:
Firstly, I have been trying to have one object read values from another, in this case it is an object called "game" reading attributes from multiple objects called "Item", the only way I can have the game object read any value from the item object is by having a method in the item class which returns the value which I want, and considering that each item has many attributes that I would like the game class to be able to read this simply does not seem like a particularly effective way to do this. So, is there any way to simply read values from an object? for example simply refering to the variable as item1.points, or item2.name, where item 2 is the object name and points is the variable name within the object?
Secondly, When I am assigning values to each item (I have the user assign certain values at the beginning of the game) is there any way to simply loop the same questions asking for values of attributes and have them assigned to my items sequentially? ie item1 then item2 then item3 rather than having selection statements to decide which item I an up to?
basically that is all I am having trouble with at the moment, any help would be greatly appreciated. Also, before anyone asks me to simply look it up, I HAVE been trying to look it up to no avail, however I may simply be using the wrong keywords to search this so any help in that regard would be much appreciated as well.
Thanks
I agree with Kyle about your first question. The java bean standard is based on accessor methods: getters and setters. IDEs like Eclipse help a lot auto generating these methods for you.
About interacting over an object properties you can use the Apacha Commons Beanutils project to do that:
// Copy properties from someObject to myTargetObject
Map attributes = BeanUtils.describe(someObject);
SomeBean myTargetObject = new SomeBean();
for(String propertyName : attributes.keySet()){
System.out.println("Value for attribute " + propertyName + " is " + attributes.get(propertyName));
// Updates target object
BeanUtils.setProperty(myTargetObject, propertyName, attributes.get(propertyName));
}
The answer to your first question is yes any field marked public will be accessible directly, but that defeats the purpose of information-hiding, which is core to OOP.
Your second question is a little bit more difficult. You can technically loop through the attributes on an object like that, but it requires you use reflection which will probably be more work than benefit.
Agree with Kyle. Also you could consider gathering those object.item_n properties into a property collection of some sort (like HashMap<String, String> textualproperties )and iterate over those or whatever.
For your first problem, make sure that both the classes are in the same package and the members are declared either public (not recommended), or protected (better) or don't specify any access specifier (which is a bit more restrictive than protected). If you follow that, both the objects belong to classes defined in the same package can access/modify each others' members without needing getters/setters.
For your second problem use reflection to go through members one by one. Look here:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/
It will tell you how to find out about a class' methods, members etc. dynamically.
I'm using Java 6.
Suppose I have a file availableFruits.txt
APPLE
ORANGE
BANANA
Suppose I want an enum FruitType that contains values listed in availableFruits.txt, will I be able to do this?
You can't populate an enum type at execution time, no - at least, not without something like BCEL, or by calling the Java compiler.
You can write code to create a Java source file, of course, and build that when you build your app, if you don't need it to be changed afterwards.
Otherwise, I'd just create a wrapper class which is able to take a set of known values and reuse them. Exactly what you need to do will depend on how you wanted to use the enum, of course.
Well the point of an Enum is to use it at compile time.
If you don't know at compile time what values your Enum has then it's not an Enum it's a collection.
If you do know and you just want to create a class file base on the values in the text file then yes it's possible by reading the txt then generating the source code.
I expect it's possible, by writing your own ClassLoader subclass, creating the bytecode for the enum in a byte array, and using defineClass. Hard, maybe, but possible. I expect once you know the byte sequence for an enum, it's not that hard to custom-generate it from the info in the JVM spec.
Now, whether it's a good idea...well, I suspect only in a very small number of edge cases. (I can't think of one; I mean, having created it, you'd have to generate code to use it, right?) Otherwise, you're probably better off with a Map or similar.
No, not unless you generate the enum source file from the text file.
As everyone else said- no. It's not possible. Your best shot is to use the Registry pattern. Read in the values, store them in some sort of query-able map. Sort of like an Enum.
As everyone pointed out, it's not possible. However, you could create a Map where the key of your map would be the value you read from you file (APPLE,ORANGE,BANANA) and the ? would be an associated valu (int for example).
This way you could basically achieve the same goal without the type safety, of course.
int i = fruitsMap.get("BANANA") // get the assoicated value
You can with dynamically generated code. e.g. Using the Compiler API. I have written a wrapper for that API so you can compile classes in memory. See the code below.
The problem you have is that its not very useful as you cannot use these values except in classes which were compiled AFTER your enum was compiled. You can use Enum.valueOf() etc. But a lot of the value of enums is lost.
As other have suggested, using a Map would be simpler and give the same benefit. I would only use the enum if you have a library has to be passed an Enum. (Or plan more generated code)
public static Class generateEnum(String className, List<String> enums) {
StringBuilder code = new StringBuilder();
code.append("package enums; public enum enums." + className + " {\n");
for (String s : enums)
code.append("\t"+s+",\n");
code.append("}");
return CompilerUtils.CACHED_COMPILER
.loadFromJava("enums."+className, code.toString());
}
One of things I find useful with text generated code is that you can write it to a file and debug it even at run time. (The library supports this) If you byte code generation, its harder to debug.
The library is called Essence JCF. (And it doesn't require a custom class loader)
How would you do this in a dynamic language like JavaScript: it would be just string with one of values: "APPLE", "ORANGE", "BANANA".
Java types (classes, interfaces, enums) exist only for compiler to do some optimizations, and type checking, to make refactoring possible, etc. At runtime you don't need neither optimizations, type checking nor refactoring, so normal "string" is OK, just like in JavaScript every object is either a number (Double in Java), a string (String in Java) or a complex object (Map in Java) - that's all you need to do anything at runtime even in Java.
On my java project, I have a bunch of strings externalized on a messages.properties file. On its respective Messages.java file I had the same number of public static String-typed attributes, so I could access those externalized texts.
Then, I implemented a method called getString, which receives the name of the constant as its argument and returns the wanted text. This way, there is no need to declare all the public static Strings-typed attributes inside the Messages.java file.
But after doing this my log became filled with "NLS unused message" messages.
Do you know if there's a way to prevent those warning messages to be logged?
Thanks in advance.
Your Messages class - it sounds like it extends org.eclipse.osgi.util.NLS.
If this is the case, it is designed to fill the requirements:
to provide compile time checking that a message exists.
to avoid the memory usage of a map containing both keys and values (this would be the case in a resource bundle approach).
good i18n support.
i.e. NLS populates the value of the Message.staticVariable with the value of the staticVariable found in messages.properties.
The warning logging provides information about a mismatch between the Messages.java and the messages.properties file.
Your getString() method sounds like it does not use any of the advantages of NLS, so as others have suggested, you may be better off using a ResourceBundle.
Messages sounds like a class you wrote, because I don't see it in my JDK 6 javadocs.
It sounds like you've tried to reinvent java.util.ResourceBundle. I'd recommend using that instead and ditching your class. It'll have the added advantage of handling I18N properly.
I don't see any value in hard-coding the public static message keys in the class. It's just another thing you'll have to maintain. If I understand what you're doing properly, I'd throw away your Messages and use ResourceBundle instead.
duffymo, as jamesh said, Messages is a class I wrote, and it extends org.eclipse.osgi.util.NLS. It has a private static attribute, and its type is... ResourceBundle!
jamesh, thanks for detailing the way NLS works.
Based on your answers I removed my Messages class from my project and added a ResourceBundle-typed attribute on the classes that need to use the externalized strings. Plus, I did it in a way that the lines accessing the externalized strings did not need to be changed.
The number of files on our project has been reduced, the code was kept as clean as before and there are no more log warnings.
Thank you, guys. You rock.
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
This is a real beginner question (I'm still learning the Java basics).
I can (sort of) understand why methods would return a List<String> rather than an ArrayList<String>, or why they would accept a List parameter rather than an ArrayList. If it makes no difference to the method (i.e., if no special methods from ArrayList are required), this would make the method more flexible, and easier to use for callers. The same thing goes for other collection types, like Set or Map.
What I don't understand: it appears to be common practice to create local variables like this:
List<String> list = new ArrayList<String>();
While this form is less frequent:
ArrayList<String> list = new ArrayList<String>();
What's the advantage here?
All I can see is a minor disadvantage: a separate "import" line for java.util.List has to be added. Technically, "import java.util.*" could be used, but I don't see that very often either, probably because the "import" lines are added automatically by some IDE.
When you read
List<String> list = new ArrayList<String>();
you get the idea that all you care about is being a List<String> and you put less emphasis on the actual implementation. Also, you restrict yourself to members declared by List<String> and not the particular implementation. You don't care if your data is stored in a linear array or some fancy data structure, as long as it looks like a List<String>.
On the other hand, reading the second line gives you the idea that the code cares about the variable being ArrayList<String>. By writing this, you are implicitly saying (to future readers) that you shouldn't blindly change actual object type because the rest of the code relies on the fact that it is really an ArrayList<String>.
Using the interface allows you to quickly change the underlying implementation of the List/Map/Set/etc.
It's not about saving keystrokes, it's about changing implementation quickly. Ideally, you shouldn't be exposing the underlying specific methods of the implementation and just use the interface required.
I would suggest thinking about this from the other end around. Usually you want a List or a Set or any other Collection type - and you really do not care in your code how exactly this is implemented. Hence your code just works with a List and do whatever it needs to do (also phrased as "always code to interfaces").
When you create the List, you need to decide what actual implementation you want. For most purposes ArrayList is "good enough", but your code really doesn't care. By sticking to using the interface you convey this to the future reader.
For instance I have a habit of having debug code in my main method which dumps the system properties to System.out - it is usually much nicer to have them sorted. The easiest way is to simply let "Map map = new TreeMap(properties);" and THEN iterate through them, as TreeMap returns the keys sorted.
When you learn more about Java, you will also see that interfaces are very helpful in testing and mocking, since you can create objects with behaviour specified at runtime conforming to a given interface. An advanced (but simple) example can be seen at http://www.exampledepot.com/egs/java.lang.reflect/ProxyClass.html
if later you want to change implementation of the list and use for example LinkedList(maybe for better performance) you dont have to change the whole code(and API if its library). if order doesnt matter you should return Collection so later on you can easily change it to Set if you would need items to be sorted.
The best explanation I can come up with (because I don't program in Java as frequently as in other languages) is that it make it easier to change the "back-end" list type while maintaining the same code/interface everything else is relying on. If you declare it as a more specific type first, then later decide you want a different kind... if something happens to use an ArrayList-specific method, that's extra work.
Of course, if you actually need ArrayList-specific behavior, you'd go with the specific variable type instead.
The point is to identify the behavior you want/need and then use the interface that provides that behavior. The is the type for your variable. Then, use the implementation that meets your other needs - efficiency, etc. This is what you create with "new". This duality is one of the major ideas behind OOD. The issue is not particularly significant when you are dealing with local variables, but it rarely hurts to follow good coding practices all the time.
Basically this comes from people who have to run large projects, possibly other reasons - you hear it all the time. Why, I don't actually know. If you have need of an array list, or Hash Map or Hash Set or whatever else I see no point in eliminating methods by casting to an interface.
Let us say for example, recently I learned how to use and implemented HashSet as a principle data structure. Suppose, for whatever reason, I went to work on a team. Would not that person need to know that the data was keyed on hashing approaches rather than being ordered by some basis? The back-end approach noted by Twisol works in C/C++ where you can expose the headers and sell a library thus, if someone knows how to do that in Java I would imagine they would use JNI - at which point is seems simpler to me to use C/C++ where you can expose the headers and build libs using established tools for that purpose.
By the time you can get someone who can install a jar file in the extensions dir it would seem to me that entity could be jus short steps away - I dropped several crypto libs in the extensions directory, that was handy, but I would really like to see a clear, concise basis elucidated. I imagine they do that all the time.
At this point it sounds to me like classic obfuscation, but beware: You have some coding to do before the issue is of consequence.