使用Java中的导入语句自动删除显式包声明

使用Java中的导入语句自动删除显式包声明,java,eclipse,refactoring,import,packages,Java,Eclipse,Refactoring,Import,Packages,我有一个由其他人创建的项目,其中包括数千个类文件,并为每个对其类的引用显式键入包名。看起来代码是逆向工程的。是否有一个好的Java工具可以重构代码,以便从类引用中删除显式类型的包前缀,并将其移动到导入语句中 先谢谢你 编辑: 我想举个例子会有帮助。我想把进口放在最上面,我不在乎有多少进口 javax.swing.JButton button1 = new javax.swing.JButton(); 想象一下上面的代码,但是在数千个类文件中的数千行代码中,几乎无处不在。我希望能够删除所有前缀,

我有一个由其他人创建的项目,其中包括数千个类文件,并为每个对其类的引用显式键入包名。看起来代码是逆向工程的。是否有一个好的Java工具可以重构代码,以便从类引用中删除显式类型的包前缀,并将其移动到导入语句中

先谢谢你

编辑:

我想举个例子会有帮助。我想把进口放在最上面,我不在乎有多少进口

javax.swing.JButton button1 = new javax.swing.JButton();
想象一下上面的代码,但是在数千个类文件中的数千行代码中,几乎无处不在。我希望能够删除所有前缀,只需要一个很好的导入javax.swing.JButton;在每个类文件的顶部。

显示:

选择PackageExplorer视图,右键单击项目,选择源,然后组织导入。Bobs您的叔叔-所有不需要的导入都被删除

要使其格式更好,请执行以下操作:

右键单击项目>源>组织导入


现在,剩下的是找到一种从代码中去除完全限定名的方法。您可能会想到一些正则表达式。看一看——这似乎很有帮助。应该也很有用。

我不知道这个用例的工具,但几个月前我不得不做类似的事情

  • 编写脚本或使用正则表达式进行搜索替换,以消除显式键入的包前缀

  • 然后让eclipse使用“组织导入”完成其余的工作。Ctrl-1

提示:为避免歧义,请使用不超过所需LIB的类路径进行设置。 大约800节课,我在2小时内完成

  • 或者找一个值得的人来做这项工作

编辑:您应该知道,在prefences/Java/Editor/Save操作中,可以将组织导入配置为保存操作。

对于单个类型,eclipse提供了“添加导入”操作(Shift+Ctrl+M)。它正是你想要的——有一个很大的限制:你必须把光标放在一个类型上,它只会影响“选中的”事件


但是,这个操作可能可以在脚本化/全局方法中使用。JDT插件可以在AST中爬行,并对找到的每种类型调用此操作。

IntelliJ Idea有工具可以根据每个文件执行此操作。你也可以批量做,但我不知道怎么做


尝试30天的评估,您可能会对导入清理功能感到满意。

您可能需要替换所有的
javax.swing。
。然后组织导入。

我对axis生成的文件也有同样的问题,为此我编写了一个小的groovy脚本。我并不是什么都做(在运行eclipse之后,您必须在eclipse中使用OrganizeImports),而且我还没有很好地测试它,所以请仔细使用它。它还限于小写的包名和驼峰大小写的类名,但这可能是一个很好的起点

def replaceExplicitPackageNamesInFile(File javaFile){
 eol = org.codehaus.groovy.tools.Utilities.eol()

 newFile = ""
 explicitImportExpr = /([^\w])(([a-z0-9]+\.)+)([A-Z][a-zA-Z0-9]+)/
 imports = ""
 javaFile.eachLine { 
  line = it.replaceAll(explicitImportExpr, {
   Object [] match ->
   imports += "import ${match[2]+match[-1]};${eol}"
   match[1]+match[-1]
  })
  newFile += line+"${eol}" 
 }
 newFile2 = ""
 newFile.eachLine { line ->
  newFile2 +=
   line.replaceAll(/(^\s*package.*$)/, {
    Object [] match ->
    match[0] + eol + imports
   } ) + eol
 }
 javaFile.setText(newFile2)
}

def replaceExplicitPackageNamesInDir(File dir){
 dir.eachFileRecurse {
  if (it.isFile() && it.name ==~ /.*\.java\z/){
   println "Processing ${it.absolutePath - dir.absolutePath}"
   replaceExplicitPackageNamesInFile(it)
  }
 }
}

通过在目标文件上运行下面的sed命令,然后在eclipse中重新组织导入,我已经能够删除接口中的所有显式包名:

sed -e 's/java\.[^ ]*\.//g;s/com\.[^ ]*\.//g'
我用的是迈克尔·恩斯特写的,你想怎么做就怎么做。它通过添加
import java.util.Collection将
java.util.Collection
等引用转换为
Collection
位于文件顶部

它实际上与对完全限定引用使用“Source->addimport”相同,只是它允许您一次对整个.java文件执行此操作

更好的是,它允许您批处理在PackageExplorer中选择的所有.java文件。只需右键单击选择并从上下文菜单中选择“源->清除限定类型声明”


Eclipse更新站点:

这不会将带有导入语句的完全限定类型声明(例如
java.awt.Font-foo
)更改为非限定类型声明(例如
Font-foo
)。至少在Eclipse3.5中是这样的。是的,我更新了我的答案,朝着这个目标迈出了下一步(实际上是上一步)。。。我将不得不研究这些,看看我可以多么容易地将其应用到我的项目中,谢谢。是的,这就是我认为我必须要做的。只有2个小时,一旦正则表达式被写入。。。听起来很有希望,而且可能正在这样做。谢谢。这可能不像删除所有显式包引用那么简单;如果存在歧义(相同的类名),则需要保留这些显式引用。使用eclipse的保存操作,至少可以更改顺序(和可见性)。如果有人有Regexp的示例,则很难为所有这些找到一个正则表达式,但您可以这样做:突出显示除现有导入列表之外的所有内容,并按CTRL-F键查找/替换。搜索“(org | com)。[a-z.]*”并确保选中了“正则表达式”和“区分大小写”选项。然后替换为“”(无)。然后“组织导入”,猜测每个导入应该是什么:我将不得不研究脚本编写,但是我不知道仅仅编写一个使用正则表达式查找和替换的脚本是否更容易。不过,如果我能找到一个已经编写好的插件,我肯定会尝试使用它。谢谢,这是错的。我们不应该偷别人的工作,我们也不应该帮助任何人这样做。@unjutable:这不是必要的偷。在这种情况下,用户有权使用lib,但原始制造商或负责人不在了,源代码和可能的错误修复也随之消失。在这种情况下,你所能做的就是扭转局面,试着自己纠正错误——没有人在窃取任何人的作品。我正在和我的大学一起进行一个研究项目,该项目有明确的权限使用和修改另一所大学的源代码。