一个C#程序员学习Java-ME的最佳方法是什么?

28

我最近开始开发Blackberry应用程序。因此,我不得不转向Java-ME并学习它及其相关工具。语法很简单,但我一直在遇到各种棘手问题和环境问题。

例如,令我惊讶并浪费了很多时间的是类对象上缺少实际属性(这是我认为所有OOP语言都有的)。还有许多问题需要注意。我去过各种地方,他们比较Java语法与C#,但似乎没有任何网站介绍转向Java时需要注意的事项。

环境是另一个问题。Blackberry IDE非常糟糕。外观让我想起Windows 3.1的Borland C ++ - 它已经那么过时了。其他问题包括不稳定的智能感知,弱调试等... Blackberry确实有Eclipse插件的Beta版本,但没有调试支持,它只是带有高级重构工具的编辑器。

那么,如何更好地适应Java-ME?


顺便问一下,“类对象上的实际属性”是什么意思? - MetroidFan2002
@MetroidFan2002 - 他所说的“真实属性”是指具有在使用时看起来像字段但在幕后具有getter/setter功能的特征。例如,使用Employee.Employer = SomeEmployer;而不是Employee.setEmployer(SomeEmployer); - Justin
我可能会尽可能地远离JavaME。Scala拥有所有美好的语言特性,当你从C#转向Java时会感到失落,但不幸的是这并不能解决可怕的生态系统问题。(是的,它在假设1995年是最先进状态时可以工作。):-/ - soc
3个回答

52

位网友不得不从C#转到Java。他列出了Java和C#的十大区别。我将采用他的主题并展示如何在Java中实现:

第十个坑 - 把我的标准输出还给我!

在Java中打印到标准输出:

System.out.println("Hello");

陷阱 #9 - 命名空间 == 自由

Java 中你没有命名空间的自由。你的类的文件夹结构必须和包名匹配。例如,一个在包 org.test 中的类必须在文件夹 org/test 中。

陷阱 #8 - super 关键字的用法

在 Java 中,要引用超类,你需要使用保留字 super,而不是 base

陷阱 #7 - 将构造函数链接到基础构造函数

在 Java 中没有这个功能。你必须自己调用构造函数。

陷阱 #6 - 怎么样才能子类化已有的类?

要在 Java 中子类化一个类,可以这样做:

public class A extends B {
}

这意味着类A是类B的子类。在C#中将是class A : B

陷阱 #5 - 为什么常量不保持恒定?

在Java中定义常量使用关键字final而不是const

陷阱 #4 - ArrayListVectorHashtable在哪里?

Java中最常用的数据结构是HashSetArrayListHashMap。它们实现了SetListMap。当然,还有更多其他类型的集合可以使用。在此处了解更多有关集合的信息。

陷阱 #3 - 访问器和修改器(Getters and Setters)

Java中没有属性的功能。您必须自己声明获取和设置方法。当然,大多数IDE都可以自动完成。

陷阱 #2 - 我不能重写吗!?

在Java中不需要声明一个方法为virtual。除了那些声明为final的方法,其他所有方法都可以在Java中被重写。

最大的陷阱...

在Java中,基本类型intfloatdoublecharlong不像C#中的Object。它们每个都有相应的对象表示,如IntegerFloatDouble等。

就是这样。别忘了查看原始链接,其中有更详细的讨论。


1
在Blackberry JDE中并不强制执行Gotcha#9,但如果您计划使用Eclipse或其他IDE,则可能希望遵守它。 - Richard

26

在纯语法层面上,Java与C#并没有显著的不同。以下是一些提示,希望对你有所帮助:

  1. 在Java中,你有两个异常家族:java.lang.Exception 及其派生类,以及 RuntimeException。这很有意义,因为在Java中异常是被检查的;这意味着如果要抛出任何非运行时异常,你还需要在方法声明中添加一个 throws 注释。因此,使用你的任何方法的方法将不得不捕获该异常或声明它也抛出相同的异常。NullPointerExceptionIllegalArgumentException等许多你认为理所当然的异常,实际上是从RuntimeException派生的,因此你不需要声明它们。检查异常是两种学科之间争议的焦点,因此我建议你自己尝试一下,看看它是否有所帮助或者是否会让你感到烦恼。就个人而言,我认为检查异常可以显著提高代码的可维护性和健壮性。

  2. 虽然Java支持自动装箱已经有一段时间了,但C#和Java之间仍然存在一些差异,你应该注意。在C#中,你可以交替使用int作为值类型和引用类型,在Java中它们实际上不是相同的类型:你会得到原始值类型int和库引用类型java.lang.Integer。这体现在两个常见方式中:你不能将值类型用作通用类型参数(所以你会使用ArrayList<Integer>而不是ArrayList<int>),并且实用方法(如parsetoString)在引用类型中静态实现(因此它不是int a; a.toString();而是int a; Integer.toString( a );)。

  • Java有两种不同类型的嵌套类,而C#只有一种。在Java中,一个没有声明static修饰符的静态类被称为内部类,并且隐式地访问封闭类的实例。这是一个重要的点,因为与C#不同,Java没有委托的概念,内部类经常用于以相对较少的语法繁琐来实现相同的结果。

  • Java中的泛型与C#采用截然不同的实现方式。开发Java泛型时决定纯粹通过语法改变而不提供运行时支持,以保留与旧版本VM的向后兼容性。由于运行时没有直接的泛型支持,Java使用一种称为类型擦除的技术来实现泛型。与C#实现泛型相比,类型擦除有很多缺点,但最重要的一点是,Java中的参数化泛型类型没有不同的运行时类型。换句话说,在编译后,类型ArrayList<Integer>ArrayList<String>等价的。如果您密集地使用泛型,您会很快遇到这些差异。

  • 在我看来,这是C#开发人员难以理解的三个最困难的方面。除此之外还有开发工具和类库。

    1. 在Java中,包(命名空间)、类名和文件名之间存在直接的对应关系。在共同的根目录下,类com.example.SomeClassorg.apache.SomeOtherClass分别对应于com/example/SomeClass.classorg/apache/SomeOtherClass.class文件。不要试图在单个Java文件中定义多个类(对于私有类是可能的,但不推荐),并且在您更熟悉开发环境之前请遵守这个目录结构。

  • 在Java中,有类路径(class-path)和类加载器(class-loader)的概念,这些概念不容易映射到C#中(虽然有一些近似的东西,但大多数.NET开发人员并不常用)。Classpath告诉Java虚拟机库和类在哪里可以找到(包括你的以及系统共享库),而你可以将类加载器看作是你的类型所处的上下文环境。类加载器用于从各种位置(本地磁盘、Internet、资源文件等)加载类型(类文件),但也限制对这些文件的访问。例如,像Tomcat这样的应用服务器将为每个注册的应用程序或上下文提供一个类加载器;这意味着应用程序A中的静态类与应用程序B中的静态类不相同,即使它们具有相同的名称,甚至共享相同的代码库。在.NET中,AppDomains提供了类似的功能。

  • Java类库类似于BCL(Base Class Library,基础类库);很多差异只是表面上的,但足以让你在整个文档(或者Google)中反复查找。不幸的是,我认为这里没有什么可做的-随着使用的不断增加,你会逐渐熟悉这些库。

  • 底线:理解Java的唯一方法就是使用它。学习曲线并不陡峭,但要准备在头两三个月的使用中经常感到惊讶和沮丧。


    2

    简短回答是 - 这会很烦人,但不难。

    Java和C#拥有相同的基本概念,并且很多库的风格非常接近,但你会一直遇到各种差异。

    如果你在谈论类属性,Java也有这些。语法是

    public class MyClass {
        public static int MY_CLASS_PROPERTY = 12;
    }
    

    我强烈建议你使用更好的集成开发环境(IDE)。任何一款Netbeans、Eclipse、IDEA或JBuider都会让你的转换过程更加愉快。


    他指的是属性,而不是字段...这是Java缺少的一个概念。基本上,它是带有语法糖的getter和setter,使它们与其他语言语法更好地融合...比如foo.Property = 5;和bar = foo.Property;(这些将访问实际方法) - Mike Stone
    问题在于你提到的IDE与Blackberry运行时集成得不太好,而且除了Eclipse之外,它们都没有仿真器支持。 - AngryHacker

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接