【问题标题】:How to convert Java code to Groovy code automatically [closed]如何自动将 Java 代码转换为 Groovy 代码 [关闭]
【发布时间】:2014-12-22 10:34:00
【问题描述】:

我已经用 Java 编写了一些代码,我需要将代码转换为 Groovy,以利用 Groovy 提供的优势。有什么方法可以自动将 Java 代码转换为 Groovy 或一些现有的插件可以让我开始朝这个方向发展?

【问题讨论】:

  • “大多数 Java 代码在语法上也是有效的 Groovy。” en.wikipedia.org/wiki/Groovy_%28programming_language%29 严格来说,您无需做任何事情。您应该更改什么完全取决于您需要 Groovy 的哪些功能。
  • 在不完全理解结果代码的情况下自动转换代码是危险的。我宁愿将现有代码放在/src/java 中(我们说的是grails,对吗?)并在重要的地方从头开始重写。就像@blagae 所说,没有需要重写它来使用它。
  • 不正确 - int[] ints = { 1,2,3 }; 是有效的 Java,但不是 Groovy。 Groovy 也没有do/while 循环,尽管它很容易模拟。还有一些 - 见groovy.codehaus.org/Differences+from+Java

标签: java grails plugins groovy


【解决方案1】:

有趣的事实 - Groovy 已经为此提供了一个工具,称为 java2groovy - 您可以在 Groovy 安装的 bin 目录中看到它。这是一个调用发行版中的类的包装脚本 - org.codehaus.groovy.antlr.java.Java2GroovyMain

不要注意添加到转换代码头部的警告:

!! NOT FIT FOR ANY PURPOSE !!

'java2groovy' cannot be used to convert one working program into another

更严肃的一点是 - 我很确定代码已经很长时间没有更新了,而且它在鼎盛时期的功能并不是很丰富。

我的建议与其他人所说的类似 - 保持原样,如果它正在工作并经过测试。如果您确实需要在 Groovy 中使用它,那么 Groovy 和 Java 之间存在一些问题差异,主要是由于 Groovy 使用 { } 字符作为闭包;需要转换使用这些(例如数组)的 Java 结构。另外,奇怪的是——Groovy 中没有 do/while 循环。在某些情况下,运行时行为与编译时不同,但 Java 使用已编译的内容。动态分派通常会产生更好的选择,因为 Groovy 会查看类型,而不是在编译时查看的样子。但是如果你期望它是一样的,那就更好了。

请参阅http://groovy.codehaus.org/Differences+from+Java 了解问题描述和一些解决方法。

【讨论】:

    【解决方案2】:

    我想用一个示例程序来展示它:

    private static List<List> subn(int n, List li) {
        List<List> ret = new ArrayList<List>();
        if (n == 0) {
            ret.add(new ArrayList());
            return ret;
        }
        if (li.isEmpty()) {
            return ret;
        }
        T x = li.get(0);
        List xs = li.subList(1, li.size());
        for (List sub : subn(n-1, xs)) {
            sub.add(0, x);
            ret.add(sub);
        }
        ret.addAll(subn(n, xs));
        return ret;
    }
    

    第一步我想删除静态类型,虽然我不反对它,但对于这么小的代码,我会去的。

    def subn(n, li) {
        def ret = new ArrayList();
        if (n == 0) {
            ret.add(new ArrayList());
            return ret;
        }
        if (li.isEmpty()) {
            return ret;
        }
        def x = li.get(0);
        def xs = li.subList(1, li.size());
        for (sub in subn(n-1, xs)) {
            sub.add(0, x);
            ret.add(sub);
        }
        ret.addAll(subn(n, xs));
        return ret;
    }
    

    这将改变字符数:) 但不会改变结构。 现在让我们更改数组文字:

    def subn(n, li) {
        def ret = [];
        if (n == 0) {
            ret.add([]);
            return ret;
        }
        if (li.isEmpty()) {
            return ret;
        }
        def x = li.get(0);
        def xs = li.subList(1, li.size());
        for (sub in subn(n-1, xs)) {
            sub.add(0, x);
            ret.add(sub);
        }
        ret.addAll(subn(n, xs));
        return ret;
    }
    

    我们看到更多的字符被修剪,现在让我们更改 if 语句。

    def subn(n, li) {
        if (n == 0) return [[]];
        if (li.isEmpty()) return [];
    
        def ret = [];
        def x = li.get(0);
        def xs = li.subList(1, li.size());
        for (sub in subn(n-1, xs)) {
            sub.add(0, x);
            ret.add(sub);
        }
        ret.addAll(subn(n, xs));
        return ret;
    }
    

    我不太喜欢短变量名,所以下一步是重命名一些变量。除此之外,我将稍微更改循环以使用 each 函数。 “it”魔术变量替换了“sub”变量。

    def subn(n, list) {
        if (n == 0) return [[]];
        if (list.isEmpty()) return [];
    
        def ret = [];
        def head = list.get(0);
        def remainder = list.subList(1, list.size());
    
        subn(n-1, remainder).each {
            it.add(0, head);
            ret.add(it);
        }
        ret.addAll(subn(n, remainder));
        return ret;
    }
    

    通过将集合相加,我们可以进一步简化循环:

    def subn(n, list) {
        if (n == 0) return [[]];
        if (list.isEmpty()) return [];
    
        def ret = [];
        def head = list.get(0);
        def remainder = list.subList(1, list.size());
    
        subn(n-1, remainder).each {
            ret.add([head] + it);
        }
        ret.addAll(subn(n, remainder));
        return ret;
    }
    

    查看代码很明显,“ret”变量只是在累积结果。为此,我们可以使用 collect 方法。

    def subn(n, list) {
        if (n == 0) return [[]];
        if (list.isEmpty()) return [];
    
        def head = list.get(0);
        def remainder = list.subList(1, list.size());
    
        def ret = subn(n-1, remainder).collect { [head] + it }
        ret.addAll(subn(n, remainder));
        return ret;
    }
    

    事实上,如果我们只是将两个集合加在一起,我们真的根本不需要“ret”:

    def subn(n, list) {
        if (n == 0) return [[]];
        if (list.isEmpty()) return [];
    
        def head = list.get(0);
        def remainder = list.subList(1, list.size());
    
        return subn(n-1, remainder).collect { [head] + it } + subn(n, remainder);
    }
    

    最后让内联 head 变量。反正它只用在一个地方,所以不值得保留。此外,我们将使用 Groovy 列表索引来删除 get() 调用。

    def subn(n, list) {
        if (n == 0) return [[]];
        if (list.isEmpty()) return [];
    
        def remainder = list.subList(1, list.size());
        return subn(n-1, remainder).collect { [list[ 0 ]] + it } + subn(n, remainder);
    }
    

    【讨论】:

    • 所有这些分号是怎么回事 ;)
    • ... 和最后一个 return 可以删除。另外,第一个 if,可以替换为:`if (!n) return [[]];
    • isEmpty()可以替换为empty
    【解决方案3】:

    我推荐这个!值得一读。 它对我有用!有点简单。

    Java To Groovy

    【讨论】:

    • 虽然这可能会回答问题,但请将相关内容发布到答案中。即使链接不起作用,这样的答案也会很有用。 (目前这是一个链接唯一的答案)
    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 2021-03-26
    • 1970-01-01
    • 2012-11-21
    相关资源
    最近更新 更多