I have recently stumbled upon a neat feature in Intellij IDEA that has let me to question one of my practices. It's the String auto-complete. Basically, if I define a key-value pair in a properties file, and then begin typing a String in java code that has the save value as the key in the properties files, IDEA can auto-complete it. More, I can navigate to it with ctrl+click and can refactor it!
The practice that I was talking about is related to displaying a value from the properties file. I am currently using an enum for this, whose types have the same name as the keys in the properties file. I was doing this because I gained type checking and refactoring. But it seems that I can have the same benefits just by using strings in IDEA (well, it doesn't really give me type checking, but it's kind of close).
I was wondering if any of you are using simple String values for retrieving messages. Is this a good practice?
I don't think it's a good practice. You shouldn't depend on your IDE when you're developing application. If somebody elses uses e.g. eclipse he has a chance to mess up all this.I like solution with enums more than string only because it gives compile time checks. You can even build you enum so it also reads properties file and every item in enum contains both key and value from property file.
A compromise would be to have an enum with properties where enum value is the property string. This way you get type safety and IDEA will recognize that enum value comes from property and let you easily navigate to it.
Its probably better to use an Enum and to make everyone you work with use intellij, if they complain show them this question (and many others).
Also worth bearing in mind that some string values require compile time constants , which makes things a bit more complex.
Related
First of all this might be a dumb question and I searched for some days but didn't find an answer. So if there is an existing answer concerning my question, I would be grateful for a link.
I don't know if anyone of you ever coded Spigot, Paper or Bukkit, but there was a class called YamlConfiguration which had the following methods:
public FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
cfg.set(path.path2, "hello");
cfg.getInt/String/...(path.path2); (which obviously returns "hello")
cfg.save(file);
The produced file then looks like this:
path:
path2: "hello"
So you could basically save any value in those files and reuse them even if your program has been restarted.
I know have moved forward from Spigot/Paper to native Java and I'm missing something like that Yaml-thing. The only thing I found was a kind of a config file, where every time the whole file is overwritten, when I try to add values.
Can you show me a proper way of saving values to a file? (would be nice without libraries)
I'm missing sth like that Yaml-thing
SnakeYAML should have you covered. Without knowing anything about your use-case, it makes no sense to discuss its usage here since its documentation already does cover the general topics.
The only thing I found was a kind of a config file, where everytime the whole file is overwritten, when I try to add values.
Saving as YAML will always overwrite the complete file as well. Serialization does not really work with append-only. (Serialization is the term to search for when you want functionality like this, by the way.)
If you mean that previous values were deleted, that probably was because you didn't load the file's content before or some other coding error, but since you don't show your code, we can only speculate.
Can you show me a proper way of saving values to a file?
People will have quite different opinions on what would be a proper way and therefore it is not a good question to ask here. It also heavily depends on your use-case.
would be nice without libraries
So you're basically saying „previously I used a library which had a nice feature but I want to have that feature without using a library“. This stance won't get you far in today's increasingly modular software world.
For example, JAXB which offers (de)serialization from/to XML was previously part of Java SE, but has been removed as of Java SE 11 and is a separate library now.
I just noticed that almost all the key values in property files are in dot separated names.
eg -some.key=some value
Does anyone know why? Just asked out of curiosity.
It's basically a convention that makes it easier to see what properties are related.
For example:
person.title="Title"
person.surname="Surname"
job.description="Some description"
It's easy to see which properties are related and, using a smart editor, you can then chose to only see the properties for person. A few IDE's and editors can even use this to add code completion for you, as you know you want to work with person, but might not remember the exact property.
We sometimes underestimate the power of readability, yet a convention like this makes it easy for anyone to add, edit or maintain these properties. This becomes very important when working in teams or when on-boarding juniors.
There is no any specific reason for that but it's just for better understanding of programmers nothing else. you can also directly write key=value without using any kind of "some" :-)
I work in a pretty large Java-project (2500+ classes) that uses an old code standard where all
member variables are prefixed with "m_" (e.g m_temperature). There is really no reason for this any longer and I'd like to get rid of them but:
In order to make the change I must do all variables at once.
It must not generate any bugs.
The first naive approach of simply renaming all the "m_variable" to just "variable" will not be sufficient as that could produce name collisions between an already existing variable named "variable", and the newly renamed one.
So, to sum up:
How do I rename all these pesky member variablest without getting into trouble and are there any more problems than the one mentioned above?
Yes, I'm aware of the refactoring/renaming features within IDEs, please bear in mind that I want to do the changes to all variables matching the criteria at once and not by right-clicking on variables and renaming them one-by-one.
How about below from : mass renaming of java variables
by Simulant
click on the variable name.
1:press [alt] + [shift] + [R]
2:enter the new name.
3:press [enter] to confirm.
-->all instances of this variable will be renamed.
Theres a question on SC which is about a massive refactoring in java too. The best answer is using japvaparser and implementing a visitor to do the actual refactoring. This shouldn't be that much work for a simple rename.
To answer your second question (are there any more problems)
I would avoid global variables. Favour encapsulation such that you can localise functionality.
I would implement some unit tests such that you can verify future changes. At the moment it appears your only available check is that your project compiles properly.
I realise both of these are potentially sizable issues in an existing project. But it's worth lookingto identify possible pain points and work on those first of all.
Refactoring tool will help in this case. When you rename a variable, it will rename it in all dependent places including if it is called in different class file. While doing this, it will alert you in case if your renamed variable matches with already existing name.
However we have to do it manually for each variable.
I don't know if this can work.
But I find this link to find and replace all occurence in a project using IntelliJ.
http://www.jetbrains.com/idea/webhelp/finding-and-replacing-text-in-project.html
If you are using eclispe IDE, you can do it in easy manner.
Steps:
select the variable
right click on it
click on refactor
click on rename
even in netbeans you can follow same steps.
The IDE finds the reference and usages and replace it all.
(First time please be gentle etc. etc.)
Let's say I was lazy/unthinking/pressed for time and hardcoded a string instead of making a global variable. And I repeated this mistake over hundreds of classes and test cases that I wrote. Now, I want to fix this, since I found out I'll eventually need to update that string. Is there some refactoring method in Eclipse or elsewhere that will let me replace all instances of that specific string with a global variable?
I can think of a programmatic solution, to run through all those files and replace the string, but I'd prefer not to go down that route unless absolutely necessary.
Thanks a lot!
Well you can use search and replace within Eclipse across all the files in your project, for one thing. You don't need to write that yourself.
It doesn't look like the "Extract Constant" refactoring of Eclipse is willing to extract it across classes, unfortunately. That would obviously be the nicer solution.
Eclipse provide Refactor option.
right click on value which you want to replace with variable, you will see option Refactor.
this will help you replace value from all other occurance.
You can find referenced place to an element in eclipse as following:
Selected element.(variable of String in your case)
Sight click on selected element
Selected menu References
Select Workspace item for finding all references in your workspace
Then you can edit evry item in result
Exist another way such as using search and replace feature.
Does anybody know of a way to convert xdoclet to annotations in an automated fashion? It seems to me that it should be possible to have equivalent annotations/annotation preprocessors for anything that xdoclet does but manually converting things is really tedious on large systems.
Offhand I don't know of anything that does this. However, it is possible to write: every JavaDoc object (such as MethodDoc) provides the position() method, which gives the source position of the associated declaration. Read the entire source file into an ArrayList by lines, for each tag prepend the appropriate annotation to the associated line (you don't want to add new lines to the list, because that would throw off the counts), then write the file back out.
An interesting solution, but I suspect that it will be better over the long run to do it manually, one set of tags at a time.