您的位置:知识库 » 编程语言

丑陋的Java API

作者: rensanning  发布时间: 2013-04-08 18:53  阅读: 1093 次  推荐: 1   原文链接   [收藏]  

  Java语言自从1995年正式推出以来,已经成为被广泛采用的编程语言之一。在TIOBE编程语言排行榜榜单上也一直保持着前几名的位置。

  《Java: The Good Parts / Java语言精粹》一书中,SUN的工程师更是大加赞扬了Java在各个方面的优点,其实Java存在很多Bad Parts需要改善。有时候开发者只是需要一个很简单的支持,但是SUN(如今是Oracle)的大师们却需要我们死很多脑细胞才能实现我们想要的。

  Tiago Fernandez曾经做过一个很有意思的投票,统计对Java API的不满意程度,EJB2.x、Date/Time/Calendar、XML/DOM、AWT/Swing、EJB3.x、Mail、Servlet/JSP、I/O等均上榜。让我们来看看这些“丑陋的Java API”吧!

  (1)臭名昭著的EJB

  这个就不多说了。虽然EJB3.x有所改善,但是开发者更能接受Spring了。

  (2)日期处理

  Java中的日期处理API是被所有的开发者深恶痛绝的!最初使用java.util.Date实现,包含了日期与时间,但是无法实现国际化。更奇怪的是属性的偏移量,月份与小时都是基于0,月份中的天数则是基于1,而年则是从1900开始的。而随着JDBC的发布,又诞生了一个java.sql.Date,它继承自java.util.Date,但却有不同的含义。IBM在1998年贡献了一个java.util.Calendar,实现了国际化,但却更复杂。

  2005年,Stephen Colebourne发布Joda-Time库,这个库非常流行并且得到了广泛的使用。Stephen Colebourne领导的JSR 310: Date and Time API已经被添加到了Java 8的特性列表中,期待有所改善吧!

  (3)异常捕获

  比如以下一个简单的反射获取字段值,需要捕获4个不同的异常:

    Field field;  
    try {  
          
        field = getClass().getField("testField");  
        Object value = field.get(this);  
          
    } catch (SecurityException e) {  
        e.printStackTrace();  
    } catch (NoSuchFieldException e) {  
        e.printStackTrace();  
    } catch (IllegalArgumentException e) {  
        e.printStackTrace();  
    } catch (IllegalAccessException e) {  
        e.printStackTrace();  
    }  

  类似的API包括:反射API、RMI API、JDBC API、 JAXP等Xml相关API、J2EE相关API(JNDI/EJB2/JMS/JavaMail等)等等。

  很多开发者不得不捕获所有的Exception和Throwable。

  XStream Thoughtworks的开源产品,采用的是xpp来进行xml和Java对象之间的转换。它不需要schema或其他的mapping文件就可以进行java对象和xml文件之间的转换,API调用起来非常方便,并且扩展功能强大。

  (4)资源释放

  在发生异常时,如果想释放资源,我们不得不先做空判断,然后再关闭,而关闭的时候还有可能继续发生异常:

    Reader in = null;  
      
    try {  
        in = new BufferedReader(new FileReader("文件名"));  
      
          
    } catch (IOException e) {  
      
    } finally {  
        if (in != null) {  
            try {  
                in.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  

  幸运的是在Java 7中提供了 try-with-resources。但是又有多少系统能够升级到Java 7呢。

    private static void customBufferStreamCopy(File source, File target) {  
        try (InputStream fis = new FileInputStream(source);  
            OutputStream fos = new FileOutputStream(target)){  
             
            byte[] buf = new byte[8192];  
      
            int i;  
            while ((i = fis.read(buf)) != -1) {  
                fos.write(buf, 0, i);  
            }  
        }  
        catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

  (5)精度计算

  在财务计算的系统中经常会使用到精度计算。Java做大数操作需要用到java.math.BigDecimal和java.text.DecimalFormat。在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。

  由于Java没有运算符重载的支持,简单的乘法也不得不写成以下这个样子:

    BigDecimal num1 = new BigDecimal("123456.789");  
    BigDecimal num2 = new BigDecimal("111.111");  
      
    BigDecimal result = num1.multiply(num2);  

  Java中long的最大值是2的63次方减1,如果你想定义一个超过int上限的long

long a = 9223372036854775807; // NG [The literal 9223372036854775807 of type int is out of range]  

  可以加个“L”:

long a = 9223372036854775807L; // OK  

  同样的有long-L、double-d、float-f。不知道为什么就不支持大数据呢。

  (6)字符串处理

  字符串处理应该是程序中使用最频繁的了,但Java提供的String方法太过于局限,虽然有StringTokenizer但是使用太复杂,所以往往我们不得不使用Commons Lang的StringUtils或者去写自己的StringUtils。

  java.lang.String / java.util.StringTokenizer

  java.lang.StringBuffer / java.lang.StringBuilder

  Apache Commons补充了很多Java的不足,已经被很多开源软件。

  http://commons.apache.org/

  (7)基本类型和包装类

  int/Integer、double/Double等共存,代码中不得不充斥着各种各样的Integer.parseInt()、Integer.valueOf()。而Java5.0开始提供基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing) ,但对于我们经常处理的比如NOT NULL限制的DB字段,很容易发生NullPointerException。

  而Map、List、Set集合类中又无法使用基本型,不得不再导入比如:Trove、Google Guava等lib。

  (8)数组与集合

  比如取个长度,数组用的属性array.length,而集合用的方法list.size()。

  泛型:

    public class Test<T> {  
        public Test() {  
            List<T> list = new ArrayList<T>(); // OK  
            T[] array = new T[3]; // NG [Cannot create a generic array of T]  
        }  
    }  

  Scala创始人Martin Odersky说当年正是因为Java泛型的丑陋才创建了Scala。

  赋值转换:

    String[] strArray = null;  
    Object[] objArray = null;  
    List<String> strList = null;  
    List<Object> objList = null;  
          
    objArray = strArray; // OK  
    objList = strList; // NG [Type mismatch: cannot convert from List<String> to List<Object>]  

  集合转数组:

  比如:ArrayList.toArray();

    ArrayList<String> stock_list = new ArrayList<String>();  
    stock_list.add("stock1");  
    stock_list.add("stock2");  
      
    String[] stockArr1 = stock_list.toArray(); // NG [Type mismatch: cannot convert from Object[] to String[]]  
    String[] stockArr2 = stock_list.toArray(new String[stock_list.size()]); // OK  
    String[] stockArr3 = stock_list.toArray(new String[0]); // OK  
    String[] stockArr4 = stock_list.toArray(new String[stock_list.size() + 10]); // OK  

  需要注意的是stockArr2和stockArr3(重新创建了一个数组返回)能正常返回我们想要的数据,但是stockArr4返回的数组长度为12,除过前两位以外都是null。

  集合类不支持基本类型:

  还是需要借助Trove、Google Guava等开源代码

  (9)日志

  Java诞生后不久log4j就发布了,并且得到了广大程序员的支持,但SUN死活不肯接受log4j 非要自己搞个log框架,自JDK 1.4发布java.util.logging日志包一来直到现在Java 1.7,许多开发者依然使用log4j或者通用的日志工具,而不是使用JDK logger。

  JSR-047(Logging API Specification)

  还有一些正在起草当中的JSR:

  JSR 317: Java Persistence 2.0(替代Hibernate)

  JSR 107: JCACHE - Java Temporary Caching API(替代EhCache)

  JSR 353: JavaTM API for JSON Processing (阿里的温绍锦是该JSR的专家组成员)

  ......

  Java的规范是有名的多而且复杂,有兴趣大家可以看看http://jcp.org/en/jsr/all,目前都排到JSR 362了。

  (10)一些易错的API

  比如:  File.mkdir()方法  String.equals()方法  以对象为Key的Map  ......

  当然,任何语言都不会是完美的,编程语言也都在不断的进化当中。Java中也还有很多相当优秀的API,比如,Doug Lea大师的java.util.concurrent包(JSR 166: Concurrency Utilities),就是功能齐全,性能卓越,优秀完美的并发库。互联网进入大数据处理时代,更加突显这个并发库的重要性。

  参考资料:

  http://stackoverflow.com/questions/238173/worst-java-practice-found-in-your-experience  http://www.youtube.com/watch?v=hcY8cYfAEwU

  http://d.hatena.ne.jp/ryoasai/20110226/1298703499

  http://dev.sei.pku.edu.cn/trac/pkuas/blog/2011/04/06/zhanglei09/my_topic

  http://www.cnblogs.com/dushu/archive/2013/01/18/2866379.html

  http://www.raychase.net/1098

标签:Java

编程语言热门文章

    编程语言最新文章

      最新新闻

        热门新闻