自动生成非通用接口实现

时间:2012-11-07 11:56:12

标签: java generics refactoring intellij-idea automated-refactoring

我有界面

public interface ObjectBuilder<E> {  
   E buildObject();
}

此外,该项目有很多类实现非通用版本的接口。

class MyClassBuilder implements ObjectBuilder {
    public MyClass buildObject() {/**/}
}

是否可以自动转换所有这些类,以便它们实现了接口的通用版本?

自动重构:

class MyClassBuilder implements ObjectBuilder<MyClass> {
    public MyClass buildObject() {/**/}
}

是否有内置或插件Intellij IDEA?或者在其他IDE?

5 个答案:

答案 0 :(得分:6)

我会做什么:搜索implements ObjectBuilder并自动将所有出现的内容替换为无法编译的内容,例如

implements ObjectBuilder<FIXME>

然后尝试编译,并手动修复所有中断。这可能比尝试使用更先进的方法更快......

答案 1 :(得分:3)

您可以使用Structural Search and Replace feature。它仅适用于Ultimate版本。

答案 2 :(得分:2)

NetBeans提供了一个名为Inspect and Transform的功能,允许您编写以下格式的自定义检查转换

<source-pattern> :: <conditions>
=> <target-pattern> :: <conditions>
;;

例如:

$f.toURL() :: $f instanceof java.io.File
=> $f.toURI().toURL()
;;

您可以在a blog post中找到更多此类转换的示例。

同样,IntelliJ通过名为 Structural Search and Replace 的功能支持自定义代码转换规则。使用IntelliJ的此功能,您可以进行如下转换:

class $TestCase$ extends TestCase {
  $MyClassContent$
}
=>
class $TestCase$ extends OurHomeGrownTestCase {
  $MyClassContent$
}

但是,我不确定上述规则语言是否足以支持您所希望的转换。如果他们无法表达您的转换,您可以随时使用IDE的重构API来自动化您的自定义转换,例如:

答案 3 :(得分:1)

您可能会对Program Transformation Systems感兴趣。

此类工具允许您根据源代码模式声明对代码的更改:“如果您看到,则将其替换为 ”。 (这有点像另一个答案中提到的可编程“结构搜索和替换”)。此类别中较强大的工具提供有关类型(“符号表”)的信息,并使其可用于控制转换(您肯定需要这样做,因为您只对将更改应用于与特定接口相关的实体感兴趣。)

这些工具还允许元编程,对这种变换的应用进行排序。有了这两个想法,人们就可以实施工具来进行“大规模”的改变,例如你想到的那种。

答案 4 :(得分:1)

  

是否可以自动转换所有这些类,以便它们实现了接口的通用版本?

是的,对于“auto”的适当定义是可能的:)

  

是否有内置或插件Intellij IDEA?或者在其他IDE?

您正在寻找的转型非常复杂:

for each class (interface) that implements ObjectBuilder (not ObjectBuilder<.*>) 
  if the class declares/defines the method buildObject with return type X 
  then 
    modify the class to implement ObjectBuilder<X> instead of ObjectBuilder. 

您可以编写一个插件来执行此操作,但我怀疑没有现有的插件具有足以描述此内容的脚本语言。

另一方面,硬编码的脚本似乎并不困难。我对IntelliJ IDEA没有任何经验,但我可以看到即使在Emnacs Lisp中使用简单的搜索/替换也可以做到这一点。