Java你不知道的那些事儿—Java隐藏特性(上)

标签: java 知道 java | 发表时间:2014-02-11 17:25 | 作者:sungang_1120
出处:http://www.iteye.com

每种语言都很强大,不管你是像我一样的初学者还是有过N年项目经验的大神,总会有你不知道的东西。就其语言本身而言,比如Java,也许你用Java开发 了好几年,对其可以说是烂熟于心,但你能保证Java所有的用法你都知道吗?今天没事就来整理下Java中有哪些隐藏的特性呢?知道的可以举手哦~~~

 

一、双括号初始化语法( DoubleBraceInitialization)(这里指的是大括号{})

 主要指的是集合类(List,Map,Set等),我们创建一个常量集合或传递一个常量集合作为参数,往往都会这么做(以Set为例):

 

Set<String> validCodes = new HashSet<String>();
 validCodes.add("XZ13s");
 validCodes.add("AB21/X");
 validCodes.add("YYLEX");
 validCodes.add("AR2D");
 removeProductsWithCodeIn(validCodes);

//或在类中初始化一个常量集合:

private static final Set<String> VALID_CODES = new HashSet<String>();
 static {
    validCodes.add("XZ13s");
    validCodes.add("AB21/X");
    validCodes.add("YYLEX");
    validCodes.add("AR2D");
 }

 

 

 会不会觉得每次都这样很费时费力,其实,有更好的办法,那就是双括号语法,像下面这样:

private static final Set<String> VALID_CODES = new  HashSet<String>() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR2D");
 }};
 
// Or:
 
 removeProductsWithCodeIn(new HashSet<String>() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR5E");
 }});
 这里解释下这两个括号:第一个括号创建了一个新的匿名内部类,相信这个大家都知道;第二个括号声明了匿名内部类实例化时运行的实例初始化块。
 

使用双括号语法需要注意两点:

1. 如果要在匿名内部类中要建立匿名子类,那么只能用于非final的类,这很明显,且不仅局限于集合类,可以用来实例化任何对象,例如用于GUI对象,如下:

add(new JPanel() {{
    setLayout(...);
    setBorder(...);
    add(new JLabel(...));
    add(new JSpinner(...));
 }});

 2, 这种语法与常用的equals( Object o)方法不兼容。例如Example类有这样的方法:

public boolean equals(final Object o) {
    if (o == null) {
        return false;
    } else if (!getClass().equals(o.getClass())) {
        return false;
    } else {
        Example other = (Example) o;
        // Compare this to other.
    }
  }

 

那么,使用双括号初始化语法创建的任何对象都不会与未使用双括号语法创建的对象相等。因此,建议大家:如果类中需要equals(Object o)方法,那就老老实实不要使用这种语法了。不过集合类没有这种问题,应该是因为集合内部优化了的原因。

那么什么时候建议大家使用双括号语法呢?

如果你只是要创建并初始化一个实例而不是创建一个新类,或者创建任何不添加字段属性或重载方法的匿名类时,用双括号语法就很nice了。

 

3. 如果你用的是集合类且该类有构造器参数接受另一个集合生成该集合的实例,那么有个更好的更惯用的替代方法,如大家都知道的List初始化可以用Arrays.asList(),如下:

 

List<String> myList = new ArrayList<String>(Arrays.asList("One", "Two", "Three"));

 但需要注意:

asList返回的是一个长度不可变的列表。数组是多长,转换成的列表是多长,我们是无法通过add、remove来增加或者减少其长度的。

 

二、类型参数的与操作&( TypeParameterJointUnion

就是参数绑定多个类型,如:

public class ClassName<T extends Class & Interface1 & Interface2 & ...> {}

 

注意:这里extends后面只有第一个为类Class,后面&的全部都是接口Interface,而且类Class的声明或定义必须在Interface之前。

 

 

举个例子:如果你想要一个既是 Comparable类又是Collection类的参数,实现的功能是:两个给定的集合是否相等或两个集合中的任一个是否包含指定的元素,那么你可以用下面的函数实现:

public static <A, B extends Collection<A> & Comparable<B>> boolean foo(B b1, B b2, A a) {
    return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);
}

 这里b1和b2可以同时具有类型Collection和Comparable类型,因此可以使用Collection类的contains方法也可以使用Comparable类的compareTo方法。

 

三、VisualVM监控工具( Java VisualVM

这是JDK6.0 update 7 中自带的监控工具(java启动时不需要特定参数,该工具在bin/jvisualvm.exe),能够监控线程,内存情况,查看方法的CPU时间和内存 中的对象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。

 

双击打开,从UI上来看,这个软件是基于NetBeans开发的了。

从界面上看还是比较简洁的,左边是树形结构,自动显示当前本机所运行的Java程序,还可以添加远程的Java VM,其中括号里面的PID指的是进程ID。OverView界面显示VM启动参数以及该VM对应的一些属性。Monitor界面则是监控Java堆大 小,Permgen大小,Classes和线程数量。Profiler界面比较有趣,看样子似乎可以动态的对某个Java程序进行调优了。不过我没试用这 个功能,感觉要调优还是在Netbeans里面比较自然一点,起码有代码,没代码调优了用处也不大。

 

四、Classpath支持通配符( Setting the class path

 

这是Java 6开始支持的功能,比如在工程中经常会有这样的配置:
java -classpath ./lib/log4j.jar:./lib/commons-codec.jar:./lib/commons-httpclient.jar:./lib/commons-collections.jar:./lib/myApp.jar so.Main
 比较复杂,还容易出错,其实可以用通配符更加简洁方便:
java -classpath ./lib/* so.Main
 

五、协变返回类型(  covariant return types

这是Java 5添加的功能,在Java5之前我们在子类中覆盖基类的方法时是不能改变被覆盖方法的返回类型的,就是基类和父类的方法必须一模一样,想要改变只能在创建 对象时Cast。Java 5过后,我们就可以改变了,不过需要注意的是:改变后的类型必须是原类型的子类型。举个例子就一目了然了。

public class CovariantReturnTypesTest {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        Mill m = new Mill();
        Grain g = m.process();
        System.out.println(g);  // output: Grain
        m = new WheatMill();
        g = m.process();
        System.out.println(g); // output: Wheat
    }
 
}
 
class Grain {
    public String toString() {
        return "Grain";
    }
}
 
class Wheat extends Grain {
    public String toString() {
        return "Wheat";
    }
}
 
class Mill {
    Grain process() {
        return new Grain();
    }
}
 
class WheatMill extends Mill {
    // 这里返回类型改为了Grain的子类型Wheat
    Wheat process() {
        return new Wheat();
    }
}

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java 知道 java] 推荐:

Java你不知道的那些事儿—Java隐藏特性(上)

- - Java - 编程语言 - ITeye博客
每种语言都很强大,不管你是像我一样的初学者还是有过N年项目经验的大神,总会有你不知道的东西. 就其语言本身而言,比如Java,也许你用Java开发 了好几年,对其可以说是烂熟于心,但你能保证Java所有的用法你都知道吗. 今天没事就来整理下Java中有哪些隐藏的特性呢. 一、双括号初始化语法( DoubleBraceInitialization)(这里指的是大括号{}).

Java中的锁(Locks in Java)

- - 并发编程网 - ifeve.com
原文链接 作者:Jakob Jenkov 译者:申章 校对:丁一. 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂. 因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字( 译者注:这说的是Java 5之前的情况).

Java 8全面解析!不知道的来看看那!

- - CSDN博客互联网推荐文章
java8的面世惊动了不少业界人员,让我们一起来看看吧. 函数式接口是只定义了一个抽象方法的接口. Java 8引入了 FunctionalInterface注解来表明一个接口打算成为一个函数式接口. 例如,java.lang.Runnable就是一个函数式接口. 注意,不管FunctionalInterface注解是否存在,Java编译器都会将所有满足该定义的接口看作是函数式接口......

你应当知道的7个Java工具

- - ImportNew
Alex Zhitnitsky告诉我们这7个辅助工具的主要功能特点,这些工具每个java程序员都应该了解一下. 这篇文章最初发表在takipi的博客–Java与Scala异常分析和性能监控.. 在准备进行锁和负载测试之前,应该对一些最新的最具创新性的工具有一个快速了解. 为了防止你错过这些信息,rebellabs最近公布了对Java工具和技术全景的一个全球性调查 结果.

java日志,需要知道的几件事

- - Java - 编程语言 - ITeye博客
java日志,需要知道的几件事. 如果对于commons-loging 、log4j 、slf4j 、LogBack 等都已经非常清楚了,可以忽略本文. 几次解决日志冲突问题时对这几个概念的简单总结,希望对这块基础没有理解透的同学能有所帮助,当然如果对这块有更深刻理解的同学,也贡献出自己的知识和见解.

Java程序员应该知道的10个调试技巧

- - 博客 - 伯乐在线
摘要:调试不仅可以查找到应用程序缺陷所在,还可以解决缺陷. 对于Java 程序员来说,他们不仅要学会如何在Eclipse里面开发像样的程序,更需要学会如何调试程序. 本文介绍了Java程序员必知的10个调试技巧,保证让你受益匪浅. 调试可以帮助识别和解决应用程序缺陷,在本文中,作者将使用大家常用的的开发工具Eclipse来调试Java应用程序.

打造高性能JAVA应用你需要知道的

- - ImportNew
这篇文章节选自《java performance》,对java性能比较关心的同学大概都知道这本书,性能这个东西可能是很多同学在日常写java code的时候很少去关心的,但是在我们写code的过程中确又时时离不开对程序性能的影响,小到我们使用位运算来实现算术运算,大到我们对JAVA代码的总体架构设计,性能其实离我们很近.

【译】你可能不知道但却很有用的 Java 特性

- - crossoverJie's Blog
在这篇文章中你将会学习到一些你可能没听过但有用的 Java 特性,这些是我个人常用的一些特性或者是从其他文章中学习到的,重点是关注 API 而不是语言本身. 众所周知,在 Java 中有许多类型的集合可以使用,但你听说过 DelayQueue 吗. 它是一个特定类型的集合,允许我们基于延时时间对数据排序,这是一个非常有意思的类,它实现了 BlockingQueue 接口,只有当数据过期后才能从队列里取出.

Java PaaS 对决

- 呆瓜 - IBM developerWorks 中国 : 文档库
本文为 Java 开发人员比较了三种主要的 Platform as a Service (PaaS) 产品:Google App Engine for Java、Amazon Elastic Beanstalk 和 CloudBees RUN@Cloud. 它分析了每种服务独特的技术方法、优点以及缺点,而且还讨论了常见的解决方法.

Java浮点数

- d0ngd0ng - 译言-电脑/网络/数码科技
Thomas Wang, 2000年3月. Java浮点数的定义大体上遵守了二进制浮点运算标准(即IEEE 754标准). IEEE 754标准提供了浮点数无穷,负无穷,负零和非数字(Not a number,简称NaN)的定义. 在Java开发方面,这些东西经常被多数程序员混淆. 在本文中,我们将讨论计算这些特殊的浮点数相关的结果.