Java 如何在Eclipse中将常量重构为枚举?

Java 如何在Eclipse中将常量重构为枚举?,java,eclipse,refactoring,Java,Eclipse,Refactoring,如何使用eclipse将Java常量重构为枚举 我发现eclipse中没有内置功能: 我发现了一个插件: . 我想知道这个插件是不是一个好办法,还是有人会用更好的方法 我总是可以自己创建一个枚举类,剪切并粘贴常量,这在2012年是很乏味的。请不要把我指向另一个IDE,我太老了,不能改变坏习惯;-) 重构永远不会改变“外部行为” 例如: public enum Test { NAME1("abc"); Test(String name) {} public stati

如何使用eclipse将Java常量重构为枚举

我发现eclipse中没有内置功能:

我发现了一个插件: . 我想知道这个插件是不是一个好办法,还是有人会用更好的方法


我总是可以自己创建一个枚举类,剪切并粘贴常量,这在2012年是很乏味的。请不要把我指向另一个IDE,我太老了,不能改变坏习惯;-)

重构永远不会改变“外部行为”

例如:

public enum Test {
    NAME1("abc");

    Test(String name) {}

    public static final String _NAME1="abc";
    public static void main(String[] args) {
        String k = Test._NAME1;
        String m = Test.NAME1;
    }
}
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);
}

}

如果将
\u NAME1
重构为
NAME1
(enum),则代码在实例化
m
时崩溃。重构永远不会成功

这里有一组自动和手动的步骤来进行重构

步骤1:封装常量上的字段

步骤2(可选)重命名常量。如果要重用这些名称,请执行此操作

步骤3(手动)使用常量值创建枚举。为枚举指定一个返回常量的getValue方法

步骤4(手动)将getter中的返回值替换为枚举中的getValue

步骤5将getter内联。选择“所有引用”和“删除方法声明”

步骤6:将常量内联。选择“所有引用”和“删除常量声明”

如果您愿意,可以在6之后停止,但要使用枚举的强大功能,还有很多工作要做

步骤7:对于每个使用enum.getValue()作为参数的方法,请用enum替换传递的常量

步骤7a更改方法签名以添加枚举作为参数

    public void method(String aConstant, AnEnum theEnum)
    ....
    public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue(), null);
}
步骤7b(手动)将enum实例作为新参数与getValue调用一起传递。确保找到所有实例,否则以后会出现问题

步骤7c(手动)在方法中,使用新的枚举参数而不是常量。如果您错过了步骤7b中的呼叫,您的测试将在此处失败

步骤7d更改方法签名以删除旧常量

步骤8(手动)对于布尔逻辑中每次使用enum.getValue()确定是否可以改用enum

        if(theEnum.equals(AnEnum.CONSTANT2))
    {
        //do something
    }
步骤9如果不再使用getValue方法,可以将其删除

步骤9a(手动)删除未使用的getValue方法

步骤9b(手动)删除构造函数中的字段和赋值

    public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}
步骤9c更改方法签名以从枚举构造函数中删除值

    public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}
步骤9d(手动)如果没有其他参数,请删除枚举构造函数中的参数

    public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}

例如:

public enum Test {
    NAME1("abc");

    Test(String name) {}

    public static final String _NAME1="abc";
    public static void main(String[] args) {
        String k = Test._NAME1;
        String m = Test.NAME1;
    }
}
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);
}

}
第一步

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;
}
步骤2重命名常量

private static final String _CONSTANT1 = "value1";
private static final String _CONSTANT2 = "value2";
...
public static String getConstant1() {
    return _CONSTANT1;
}

public static String getConstant2() {
    return _CONSTANT2;
}
    public static enum AnEnum {
    CONSTANT1("value1"), CONSTANT2("value2");
步骤3创建枚举

    public static enum AnEnum {
    CONSTANT1(_CONSTANT1), CONSTANT2(_CONSTANT2);

    private final String value;

    AnEnum(String aValue)
    {
        value = aValue;
    }

    public String getValue()
    {
        return value;
    }
}
步骤4替换常量getter中的返回值

    public static String getConstant1() {
    return AnEnum.CONSTANT1.getValue();
}

public static String getConstant2() {
    return AnEnum.CONSTANT2.getValue();
}
public void method(String aConstant)
{
    if(aConstant.equals(AnEnum.CONSTANT2.getValue()))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue());
}
步骤5将常量getter内联

    public static String getConstant1() {
    return AnEnum.CONSTANT1.getValue();
}

public static String getConstant2() {
    return AnEnum.CONSTANT2.getValue();
}
public void method(String aConstant)
{
    if(aConstant.equals(AnEnum.CONSTANT2.getValue()))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue());
}
步骤6:将常量内联

private static final String _CONSTANT1 = "value1";
private static final String _CONSTANT2 = "value2";
...
public static String getConstant1() {
    return _CONSTANT1;
}

public static String getConstant2() {
    return _CONSTANT2;
}
    public static enum AnEnum {
    CONSTANT1("value1"), CONSTANT2("value2");
步骤7a更改方法符号以添加枚举作为参数

    public void method(String aConstant, AnEnum theEnum)
    ....
    public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue(), null);
}
步骤7b将enum实例作为新参数与getValue调用一起传递

    public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue(), AnEnum.CONSTANT1);
}
步骤7c使用新的枚举参数,而不是旧的传递值

        if(theEnum.getValue().equals(AnEnum.CONSTANT2.getValue()))
    {
步骤7d更改方法签名以删除旧常量

public void method(AnEnum theEnum)
....

public void anotherMethod()
{
    method(AnEnum.CONSTANT1);
}
步骤8:对于布尔逻辑中每次使用的enum.getValue(),确定是否可以改用enum

        if(theEnum.equals(AnEnum.CONSTANT2))
    {
        //do something
    }
步骤9a删除未使用的getValue方法 步骤9b(手动)删除构造函数中的字段和赋值。 步骤9c更改方法签名以从枚举构造函数中删除值。 步骤9d(手动)如果没有其他参数,请删除枚举构造函数中的参数

    public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}
最后代码如下所示:

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);
}

}

+1我不确定其他IDE是否也有此功能。在这种情况下,正则表达式替换也是一个很好的解决方案。这些常量是类级还是项目级?@UnniKris类级常量。这是一个eclipse。抱歉,我想这就是为什么对枚举的重构永远不会是eclipse的一部分。重命名字段、重命名方法等。,两者都可能导致这种冲突,Eclipse支持它们。OKI希望将类私有常量提取到枚举类中(并可能使其非私有)。感谢您的回答。@artbristol rename不会改变外部行为,因此ok@PeterRader你能解释一下“外在行为”是什么意思吗?