28 二月 2024
将某些项目从一种语言翻译为另一种语言不仅涉及源代码更改,还涉及我们执行该项目的环境。CodePorting.Translator Java Class Library 确实通过 JCL (Java class library) 实现了这样的环境,保留了.NET Framework类库的逻辑和结构,这使得翻译的项目感觉宾至如归,将其隐藏在Java平台实现之外。
JCL(Java Class Library)在通用设计、异常处理和逻辑方面与 .NET 类库存在差异。因此,如果我们决定将代码从 C# 转换到 Java,仅仅替换类和函数的名称是不安全的。有一种解决方案可以生成包装代码,重现 .NET Framework 类库的逻辑。但这样一来,生成的 Java 代码将与原始 C# 代码大相径庭,这并不是我们所期望的 – 我们希望翻译器保持原始程序结构。因此,我们有必要实现.NET 框架类库的 Java 替代。
让我们从简单的事情开始:
using System;
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, Example!");
}
}
我们这里有一个来自 .NET Framework 类库的类 – System.Console
。
翻译后的 Java 代码看起来如何?
import com.codeporting.ms.System.Console;
class Program
{
public static void main(String[] args)
{
Console.writeLine("Hello, Example!");
}
}
正如您所看到的,该翻译器确实将 C# System.Console
类的引用替换为 Java com.codeporting.ms.System.Console
类,在CodePorting.Translator Java Class Library中实现。
好吧,现在让我们看另一个例子:
using System;
using System.Collections.Generic;
class Program
{
public static void Main(string[] args)
{
PrintList(new List<string> { "Hello, list!", "I have a list for you to print!" });
}
public static void PrintList(List<string> list)
{
foreach(var item in list) Console.WriteLine(item);
}
}
翻译后的 Java 代码如下:
import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Collections.Generic.List;
import com.codeporting.ms.System.Console;
import com.codeporting.ms.System.IDisposable;
import java.util.Iterator;
class Program
{
public static void main(String[] args)
{
List<String> tmp = new List<String>();
tmp.addItem("Hello, list!");
tmp.addItem("I have a list for you to print!");
printList(tmp);
}
public static void printList(IGenericEnumerable<String> list)
{
//Foreach to while statement conversion
Iterator<String> variable1 = list.iterator();
try
{
while (variable1.hasNext())
{
String item = variable1.next();
Console.writeLine(item);
}
}
finally
{
if (variable1 != null)
{
((IDisposable)variable1).dispose();
}
}
}
}
在这里,我们看到了使用 CodePorting.Translator Java Class Library 的另一个好处 – 我们保持了 C# 抽象之间的关系。System.Collections.Generic.List
实现了 IEnumerable
接口,这使我们能够使用 foreach
循环遍历它。Java 有java.lang.Iterable
接口,它看起来与 IEnumerable
类似,但它们在设计上有细微差别,这可能会对大型项目产生决定性影响。
尽管我们有一个很好的库可供使用,但我们翻译的项目确实需要可供客户访问和理解,并且他们可能更喜欢使用 JCL 类。 如果我们使用 CodePorting.Translator Java Class Library,那么对外界来说是一件好事。 而且,这里我们还有另一个有趣的 CodePorting.Translator 功能:ApiChange。 这个功能有什么作用? 它隐藏使用 CodePorting.Translator Java Class Library的方法,创建使用 JCL 类的代理方法。 让我们看一下例子:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Newspaper
{
public class Article
{
public DateTime Published { get; set; }
public string Content { get; set; }
}
public class Archive
{
List<Article> articles = new List<Article>();
public void AddArticle(Article article)
{
articles.Add(article);
}
public IEnumerable<Article> GetArticlesForPeriod(DateTime start, DateTime end)
{
if(start > end || start > DateTime.Now)
{
return new Article[0];
}
return articles.Where(article => article.Published >= start && article.Published <= end);
}
}
public class Program
{
public static void Main(string[] args)
{
var archive = new Archive();
archive.AddArticle(
new Article() {
Published = new DateTime(2012, 12, 20), Content = "End of the world comes tomorrow!" });
archive.AddArticle(
new Article() {
Published = new DateTime(2012, 12, 22), Content = "It was a huge joke..." });
var articles = archive.GetArticlesForPeriod(
new DateTime(2000, 1, 1),
new DateTime(2012, 12, 21));
foreach(var article in articles)
{
Console.WriteLine(article.Content);
}
}
}
}
您可以在这里看到一个简单的类 Archive
,它存储了一些文章并提供访问这些文章的功能,根据文章发表的日期进行筛选。
类 System.DateTime
是 .NET Framework 类库的一部分,尽管我们可能会在项目中使用它,但我们希望对外部世界隐藏它:
Article.java
package Newspaper;
import com.codeporting.ms.System.DateTime;
import java.util.Date;
public class Article
{
private DateTime auto_Published = new DateTime();
final DateTime getPublishedInternal() { return auto_Published.Clone(); }
public final Date getPublished() {
return DateTime.toJava(getPublishedInternal());
}
final void setPublishedInternal(DateTime value) { auto_Published = value.Clone(); }
public final void setPublished(Date value) {
setPublishedInternal(DateTime.fromJava(value));
}
private String auto_Content;
public final String getContent() { return auto_Content; }
public final void setContent(String value) { auto_Content = value; }
}
Archive.java
package Newspaper;
import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Collections.Generic.List;
import com.codeporting.ms.System.DateTime;
import com.codeporting.ms.System.Func;
import java.util.Date;
public class Archive
{
private Archive[] Archive_this = {this};
private List<Article> articles = new List<Article>();
public final void addArticle(Article article)
{
articles.addItem(article);
}
final IGenericEnumerable<Article> getArticlesForPeriodInternal(DateTime start, DateTime end)
{
if(DateTime.op_GreaterThan(start, end) || DateTime.op_GreaterThan(start, DateTime.getNow()))
{
return com.codeporting.ms.System.Array.<Article>toGenericList(new Article[0]);
}
return articles.where(new Func<Article,Boolean>() {
public String getDelegateId() {
return System.identityHashCode(Archive_this[0]) + "-89480671";
}
public Boolean invoke(Newspaper.Article article) {
return DateTime.op_GreaterThanOrEqual(article.getPublishedInternal(), start)
&& DateTime.op_LessThanOrEqual(article.getPublishedInternal(), end);
}
});
}
public final java.lang.Iterable<Article> getArticlesForPeriod(Date start, Date end)
{
IGenericEnumerable<Article> temp=getArticlesForPeriodInternal(
DateTime.fromJava(start),
DateTime.fromJava(end));
java.util.ArrayList<Article> temp_java=new java.util.ArrayList<Article>();
{
com.codeporting.ms.System.Collections.Generic.IGenericEnumerator<Article> temp_iterator=temp.iterator();
while(temp_iterator.hasNext())
{
Article element=temp_iterator.next();
temp_java.add(element);
}
}
return temp_java;
}
}
Program.java
package Newspaper;
import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Console;
import com.codeporting.ms.System.DateTime;
import com.codeporting.ms.System.IDisposable;
import java.util.Iterator;
public class Program
{
public static void main(String[] args)
{
Archive archive = new Archive();
Article tmp = new Article();
tmp.setPublishedInternal(new DateTime(2012, 12, 20));
tmp.setContent("End of the world comes tomorrow!" ) ;
archive.addArticle(tmp);
Article tmp_1 = new Article();
tmp_1.setPublishedInternal(new DateTime(2012, 12, 22));
tmp_1.setContent("It was a huge joke..." ) ;
archive.addArticle(tmp_1);
IGenericEnumerable<Article> articles = archive.getArticlesForPeriodInternal(
new DateTime(2000, 1, 1),
new DateTime(2012, 12, 21));
//Foreach to while statement conversion
Iterator<Article> variable1 = articles.iterator();
try
{
while (variable1.hasNext())
{
Article article = variable1.next();
Console.writeLine(article.getContent());
}
}
finally
{
if (variable1 != null)
{
((IDisposable)variable1).dispose();
}
}
}
}
翻译成 Java 的代码无法通过 公共 API 访问 CodePorting.Translator Java Class Library,并且外部 Java 世界可以使用公共代理方法与我们的 Archive
类进行交互。
CodePorting.Translator Java Class Library 确实提供了一个抽象层和对 JCL 的控制,这分散了我们对实现细节的注意力,并允许我们思考我们解决的问题。 它还有助于保持原始代码的结构,提高翻译结果的理解力和透明度。