Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过重构简化代码_Java_C_Refactoring - Fatal编程技术网

Java 通过重构简化代码

Java 通过重构简化代码,java,c,refactoring,Java,C,Refactoring,是否有一个重构工具,无论是针对C还是Java,都可以简化这种类型的冗余代码。我相信这就是所谓的数据传播 这本质上就是优化编译器要做的事情 public int foo() { int a = 3; int b = 4; int c = a + b; int d = c; System.out.println(c); return c; } 进入 我认为这不是一个好主意 例如,以下代码: long hours = 5; long timeInMil

是否有一个重构工具,无论是针对C还是Java,都可以简化这种类型的冗余代码。我相信这就是所谓的数据传播

这本质上就是优化编译器要做的事情

public int foo() {
    int a = 3;
    int b = 4;
    int c = a + b;
    int d = c;
    System.out.println(c);
    return c;
}
进入


我认为这不是一个好主意

例如,以下代码:

long hours = 5;
long timeInMillis = hours * 60 * 1000;
这比仅仅:

long timeInMillis = 300000;

代码的语义信息可能会丢失。可能的依赖关系可能会中断。简而言之:只有程序员知道哪些变量是重要的或可能变得重要,因为只有程序员知道代码的上下文。恐怕您必须自己进行重构

是的,在他们的社区版中提供了此功能。现在,为了解决一个更严重的问题,我敢肯定您将编译与重构混为一谈。当你编译一些东西时,你使用一种高于机器代码的语言,并将其转换成机器代码(本质上)。您想要的是删除高级语言(即程序文件、.c、.java等)中冗余的声明。很可能编译器已经将不太好的代码优化为您所建议的代码,有工具可以查看它正在做什么。在重构方面,更少的代码通常更好,但不要为了更少的代码行而牺牲可维护性。

如果你说的是C,你可以看看编译过的、优化过的汇编代码。然后可以将C代码重构为与优化程序集相同的结构。不过,正如Alfredo所说,这可能会导致代码更加模糊。

为什么不使用优化编译器编译代码呢。然后反编译代码。这只是我的想法,我还没有尝试过。

是的,我见过人们使用的最好的重构工具是他们的大脑

大脑似乎是一个非常好的工具,可以逻辑地组织代码供其他大脑使用。在适当的情况下,它还可以用于通过注释增强代码,并通过布局和命名赋予额外的含义

编译器非常适合优化代码,以便更接近构成处理器的晶体管的底层使用。更高一代编程语言的一个好处是,它不像机器制造的东西


道歉,如果这似乎有点油嘴滑舌和无益。我当然使用过各种各样的工具,但我不记得有任何处理“数据传播”的工具。

我可以为C提供一个解决方案。我的解决方案使用了我在另一个答案中描述的两个工具(顺序相反)

这是您的程序,翻译成C:

int foo() {
    int a = 3;
    int b = 4;
    int c = a + b;
    int d = c;
    printf("%d", c);
    return c;
}
步骤1:恒定传播 步骤2:切片
一种可能的方法是将其放入一个符号数学程序(如Mathematica或Maple),并让它为您进行简化。不管它们是否为常量,它都会这样做

缺点是需要将代码转换为其他语言。(虽然如果语法相似,它可能主要是复制和粘贴。)此外,如果您期望某些整数类型以特定的大小溢出,则可能是危险的。符号数学程序不在乎,会根据“数学”对其进行优化。浮点舍入错误也是如此

在您的示例中,如果您将其输入Mathematica:

a = 3;
b = 4;
c = a + b;
d = c;
c
7
将在Mathematica中输出:

a = 3;
b = 4;
c = a + b;
d = c;
c
7
当然,你不能只是复制和粘贴,因为这是一种不同的语言和不同的语法,但这是我对你的问题最好的想法。在我将Mathematica应用到C/C++之前,我自己使用Mathematica来简化表达式和其他数学

对于涉及未知的更复杂示例:

原始C代码:

int a = 3 + x*x;
int b = 4 + y*y;
int c = a + b - 7 + 2*x*y;
int d = c;
将此输入Mathematica(它仍然主要是复制+粘贴):

输出:

(x + y)^2
将其转换回以下C代码:

d = (x + y)
d = d * d;
这显然比原始代码简单得多。一般来说,符号程序甚至可以处理非平凡的表达式,其性能与任何内部编译器一样好(甚至更好)

最后一个缺点是像Mathematica或Maple这样的符号数学程序不是免费的,而且相当昂贵。SAGE是一个开源程序,但我听说它没有Mathematica或Maple好。

Eclipse(我相信NetBeans和IntelliJ)几乎有所有这些重构可用。我将给出Eclipse的细节。首先:

public int foo() {
    int a = 3;
    int b = 4;
    int c = a + b;
    int d = c;
    System.out.println(c);
    return c;
}
首先,
d
将显示一条警告,说明您有一个未读的局部变量<代码>+1在该行,然后选择“删除d和所有分配”。那么你有:

public int foo() {
    int a = 3;
    int b = 4;
    int c = a + b;
    System.out.println(c);
    return c;
}
接下来,突出显示
int c=a+b中的
a
并将
++I
键入内联
a
。重复
b
,您将获得:

public int foo() {
    int c = 3 + 4;
    System.out.println(c);
    return c;
}
现在你就快到了。我不知道如何通过重构将3+4转换为7。对于某人来说,它似乎很容易实现,但可能不是一个常见的用例,因为其他人已经指出,根据领域的不同,3+4可能比7更具表现力。您可以进一步内联
c
,为您提供:

public int foo() {
    System.out.println(3 + 4);
    return 3 + 4;
}

但是,如果不知道原始代码的“真正”问题,就不可能知道这是一种改进还是一种倒退。

如果编译器仍然这样做,为什么要这样做?这里有两种转换:“常数传播”和“常数折叠”。但这并不是你正在摆脱的“冗余”代码;这是不必要的代码。有人认为“不必要的”代码是用来区分问题的。(当然,有些可能只是愚蠢而已)。如果a和b的值不再是3和4呢?@undur_gongor:原因是错误的空间越小,一般来说,代码越少,错误就越少。@Jack:是的,但对于重构,代码必须是正确的。我想在大多数情况下,复杂的代码在可维护性方面会更好
public int foo() {
    int c = 3 + 4;
    System.out.println(c);
    return c;
}
public int foo() {
    System.out.println(3 + 4);
    return 3 + 4;
}