How do I refactor Java constants to enums with eclipse?
I found no built-in functionality in eclipse: http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fref-menu-refactor.htm
I found a plugin: http://code.google.com/p/constants-to-enum-eclipse-plugin/. I'm wondering whether the plugin is the way to go or anyone uses a better approach.
I could always create an enum class myself an cut&paste the constants which is tedious in 2012. Please don't point me to another IDE, I'm too old too change bad habits ;-)
An enum can, just like a class , have attributes and methods. The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden).
An enum is a special class that represents a group of constants. To create an enum, use the enum keyword (instead of class or interface), and separate the constants with a comma. values() method can be used to return all values present inside enum.
Refactoring using EclipseRight clicking on a Java element in the Package Explorer view and selecting Refactor menu item. Right clicking on a Java element in the Java editor and selecting Refactor menu item. Selecting a Java element in either the Package Explorer view or Java Editor and clicking Shift + Alt + T.
Solution. An Enum can only be changed in Edit Mode. If you try to change it in runtime, you will get the error. You can't edit an Enum in runtime.
Here are a set of automated and manual steps to do this refactoring.
Step 1 Encapsulate field on the constants
Step 2 (Optional) Rename the constants. Do this if you want to reuse the names.
Step 3 (Manual) Create the enum using the values of the constants. Give the enum a getValue method that return the constant.
Step 4 (Manual) Replace the return value in the getters with getValue from the enum.
Step 5 Inline the getters. Choose "All References", and "Delete method declaration".
Step 6 Inline the Constants. Choose "All References", and "Delete constant declaration".
You can stop after 6 if you want, but there is more to be done to use the power of enums.
Step 7 For each method that uses enum.getValue() as a parameter, replace the constant was passed with the enum.
Step 7a Change Method Signature to add the Enum as a parameter.
Step 7b (Manual) Pass the enum instance as the new parameter alongside the getValue call. Make sure you find all the instances, or there will be problems later.
Step 7c (Manual) In the method, use the new enum parameter instead of the constant. If you missed a call in step 7b your tests will fail here.
Step 7d Change Method Signature to remove the old Constant.
Step 8 (Manual) For each use of the enum.getValue() in boolean logic determine if you can use the enum instead.
Step 9 If the getValue method is no longer used it can be removed.
Step 9a (Manual) Delete the unused getValue method
Step 9b (Manual) Delete field and assignment in the constructor.
Step 9c Change Method Signature to remove the value from the enum constructor.
Step 9d (Manual) If no other parameters, Remove the the enum constructor.
For example:
public class Initial {
public static final String CONSTANT1 = "value1";
public static final String CONSTANT2 = "value2";
public void method(String aConstant)
{
if(aConstant.equals(CONSTANT2))
{
//do something
}
}
public void anotherMethod()
{
method(CONSTANT1);
}
}
Step 1
private static final String CONSTANT1 = "value1";
private static final String CONSTANT2 = "value2";
public void method(String aConstant)
{
if(aConstant.equals(getConstant2()))
{
//do something
}
}
public void anotherMethod()
{
method(getConstant1());
}
public static String getConstant1() {
return CONSTANT1;
}
public static String getConstant2() {
return CONSTANT2;
}
Step 2 Rename Constants
private static final String _CONSTANT1 = "value1";
private static final String _CONSTANT2 = "value2";
...
public static String getConstant1() {
return _CONSTANT1;
}
public static String getConstant2() {
return _CONSTANT2;
}
Step 3 Create Enum
public static enum AnEnum {
CONSTANT1(_CONSTANT1), CONSTANT2(_CONSTANT2);
private final String value;
AnEnum(String aValue)
{
value = aValue;
}
public String getValue()
{
return value;
}
}
Step 4 Replace return value in Constant getters
public static String getConstant1() {
return AnEnum.CONSTANT1.getValue();
}
public static String getConstant2() {
return AnEnum.CONSTANT2.getValue();
}
Step 5 Inline the constant getters
public void method(String aConstant)
{
if(aConstant.equals(AnEnum.CONSTANT2.getValue()))
{
//do something
}
}
public void anotherMethod()
{
method(AnEnum.CONSTANT1.getValue());
}
Step 6 Inline the Constants
public static enum AnEnum {
CONSTANT1("value1"), CONSTANT2("value2");
Step 7a Change Method Signiture to add enum as parameter.
public void method(String aConstant, AnEnum theEnum)
....
public void anotherMethod()
{
method(AnEnum.CONSTANT1.getValue(), null);
}
Step 7b Pass the enum instance as the new parameter alongside the getValue call
public void anotherMethod()
{
method(AnEnum.CONSTANT1.getValue(), AnEnum.CONSTANT1);
}
Step 7c Us the new enum parameter instead of the old passed value.
if(theEnum.getValue().equals(AnEnum.CONSTANT2.getValue()))
{
Step 7d Change Method Signature to remove the old Constant
public void method(AnEnum theEnum)
....
public void anotherMethod()
{
method(AnEnum.CONSTANT1);
}
Step 8 For each use of the enum.getValue() in boolean logic determine if you can use the enum instead.
if(theEnum.equals(AnEnum.CONSTANT2))
{
//do something
}
Step 9a delete the unused getValue method Step 9b (Manual) Delete field and assignment in the constructor. Step 9c Change Method Signature to remove the value from the enum constructor. Step 9d (Manual) If no other parameters, Remove the the enum constructor.
public static enum AnEnum {
CONSTANT1, CONSTANT2;
}
So finally the code looks like this:
public class Step9d {
public static enum AnEnum {
CONSTANT1, CONSTANT2;
}
public void method(AnEnum theEnum)
{
if(theEnum.equals(AnEnum.CONSTANT2))
{
//do something
}
}
public void anotherMethod()
{
method(AnEnum.CONSTANT1);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With