【问题标题】:Auto generify non-generic interface implementation自动生成非泛型接口实现
【发布时间】:2012-11-07 11:56:12
【问题描述】:

我有界面

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

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

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

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

自动重构为:

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

是否有内置或插件的 Intellij IDEA?还是在其他IDE中?

【问题讨论】:

  • 我无法想象有什么如此具体(尽管可以证明我错了!),我怀疑搜索/替换可能是要走的路
  • IntelliJ 中什么都没有;它被“参数化类的原始使用”检查拾取,但没有快速修复选项。
  • 刚刚尝试在 Eclipse 中处理您的文件。. 也没有用 :-)
  • @turbanoff 我们在谈论多少个课程?许多?数百?

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


【解决方案1】:

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

implements ObjectBuilder<FIXME>

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

【讨论】:

  • 它会破坏现有的、正确的接口实现
  • 只要搜索正则表达式“implements\s+ObjectBuilder\s*{”。 Eclipse 可以做到这一点(Ctrl+H,文件选项卡,替换按钮在底部)。
【解决方案2】:

您可以使用Structural Search and Replace feature。不过它只在终极版中可用。

【讨论】:

    【解决方案3】:

    NetBeans 提供了一个名为Inspect and Transform 的功能,它允许您编写自定义的inspectionstransformations,格式如下:

    <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 来自动化您的自定义转换,例如:

    【讨论】:

      【解决方案4】:

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

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

      此类工具还允许元编程,对此类转换的应用进行排序。有了这两个想法,您就可以实施工具来执行“大规模”更改,例如您考虑的那种更改。

      【讨论】:

        【解决方案5】:

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

        是的,对于“自动”的适当定义,这是可能的:)

        是否有内置或插件的 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 中使用简单的搜索/替换也可以做到这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 2020-02-19
          • 2020-03-02
          • 1970-01-01
          • 2012-10-21
          相关资源
          最近更新 更多