Renaming a lot of variables in many Java classes at once - java

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.

Related

How to split a Java library source into two blocks, keeping one package?

We are creating an android library for use with Android. That means an Eclipse-like IDE and an Ant-like build process.
The nature of the library is that it has two distinct parts, representing different levels of abstraction - let's say 'upper' and 'lower'.
Assume, for the purposes of this question, that we need to call methods in one part from the other, but would like to keep those methods hidden from the library user. I've scoured the usual references but they all stop at the point of explaining package name conventions and scope rules. I've failed to find anything that answers this on SO, though this was useful.
The immediate solution is to simply have everything in one package and for those methods to be package-private. However, for reasons of maintainability, clarity, and not-having-100-files-in-one-folder we'd prefer to split the parts into different folders.
The obvious splitting point is to split the (let's say 'wibble') package into com.me.wibble.upper and com.me.wibble.lower packages/folders, but that makes any interconnecting methods undesirably public. In mitigation they could be hidden from the javadoc with #hide.
Another thought is whether could we split the parts at the top level and instead of the classic /main and /test folders have /upper, /lower and /test and all parts share the same com.me.wibble namespace. I'm unsure if/how Eclipse would cope with that.
Is there a conventional way of doing this, or is it just not done? If there are ways, what are the pro's and con's?
hmmm......Instead of asking for the solution, sometimes it is better to give the question. WHY you want library users to have a restricted view may generate a better answer than the HOWTO. There are a few answers I thought of but didn't give because I don't know the motivation behind the question (I don't want to waste your time with an answer that is not applicable).
/upper,/lower/,/test doesn't make your situation any nicer. It just makes the project more organized. Whether they are all in the same folder or separate it doesn't affect much.
It sounds like you need public 'interfaces' for library users while having private 'interfaces' for your own use. This is possible with hacking but can be painful if this is large pre-existing collection of code.

Intellij IDEA String handling features and retriving messages from properties files

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.

Refactor hardcoded variable across multiple classes into one global variable?

(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.

Refactoring tool in Eclipse

My need is pretty simple: I want to change a method call objClass1.method1() by a call objClass2.method2() in my whole Eclipse project. Unfortunately, I can't find a plugin able to do this. Can you help?
Edit:
To be more accurate, objClass1 is part of a third party library, so I need to change the method calls. I can't start at the method definition. When I right-click on a method1 call, I have no "rename" option in my "Refactor" menu.
I don't want to change or rename my methods. I want to exchange one call by another in my whole project.
An example of what needs to be done:
Before refactoring:
Injector injector=Guice.createInjector(new IContactModule());
After refactoring:
Injector injector=IContactInjectorSingleton.getInjector();
And this needs to be done a several points in my project.
What you ask for is no refactoring. A refactoring is defined as "a change that alters the code while not changing the behavior of the code". In this sense renaming a class or renaming a method is a refactoring (you change the code but the program does the same as before). But what you suggest does NOT preserve the behavior of the code so there will never be a "refactoring" for this.
Of course one might be able to write a plugin that is able to perform the text changes you want in a more or less safe way. But this will only work in very specific circumstances (what if your new method needs an argument the old one dons't need? What if there are more than one method with the same name but different parameters? ...). So I don't believe such a plugin exists, nor it makes much sense to develop such a plugin.
Just right click on the class/method name and choose Refactor > Rename.
EDIT:
To be more accurate, objClass1 is part of a third party library, so I need to change the method calls. I can't start at the method definition. When I right-click on a method1 call, I have no "rename" option in my "Refactor" menu.
Hence I would suggest you to simply make a replacement:
Search menu > File, type the old name, choose the context of the search ("Enclosing project"), click on Replace and type the new name.
EDIT2:
From the example you added to the question I think that a manual replacement, using the tool I just suggested, it's the best way. It's a complex issue, as #Arne pointed out, so it's better to make it in a controlled way. Moreover I doubt it is such a frequent operation to require a plugin to be built.
You could use the eclipse refactoring by selecting the methods name. Right click for context menu or Alt-Shift-R, in the Rename-Dialog a preview dialog is available which shows all suggested changes in one place.
First, move the body of objClass1.method1() into objClass2.method2(), and have method1 simply call method2. It may not be quite as "simple" as that, if for instance method1 uses fields of Class1 for instance, in which case you should probably include this as a parameter to the new method and perhaps use getters for the fields. If you can make the method static before doing this, it will be easier to avoid those kinds of problems. Anyway, make that transformation, so method1 is just calling method2. Now use the Inline Method refactoring to make method1 go away. You're done.

Can I compile a class along with all of its inner classes to a single class file?

I've been working on a fairly simple project for a class. I knew it was supposed to be written in Java, and I read enough of the Assignment description to have an idea what I was supposed to be doing, so I set about creating a nice, object-oriented solution ('cause it's Java, right?). When I finally get to reading the nitty-gritty details of the assignment, I come upon this little gem: The whole thing is supposed to be submitted as a single class file. It's too late to rewrite the whole thing now, so I tried to work around it by making all my classes static inner classes of the primary class. To my chagrin, I discovered that eclipse, at least by default, compiles the inner classes to separate class files still. I unfortunately don't know much about Java compiler settings, but I'm hoping theres a way to get them all compiled to one .class file. Is is it possible, or must I simply turn in what I've got with a note and take whatever my TA decides to dock me for it?
I'm afraid there is no such option. Each class is defined in its own class file. Even anonymous classes are defined in ParentClass$1.class
What I would suggest is to put a huge comment/documentation on why you think it is not good to put everything in one class. Of course it depends on the person "on the other end".
If one file, rather than one class is required, simply make a jar file.
If you are feeling brave you could create a jar for your application, encode it as a string in a your toplevelclass which extends a classloader and use this classloader to load the classes from the decoded jar file.
This is so crazy and shows so much knowledge of the Java platform it has to be worth extra credits.
As a TA, if a student send me a single java file, with an object-oriented design and nested classes, I would love it!
If the TA wanted the simplest solution to the problem and you over-engineered it, than it's of course another story.
Note that if the TA does not like nested classes and think they are bad, point him to NewSpeak and Gilad Bracha's posts. He's been involved in the Java Language Specification, he is an authority in the field and came up with a language entirely based on class nesting!
That said, should this be a single file, or single class file. If the former you can of course ZIP/JAR it, if the latter a little chat with the TA would be the way to go.

Categories