`
ol_beta
  • 浏览: 282729 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

Java 中的语法糖 (Syntactic Sugar)

    博客分类:
  • java
阅读更多

语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语。指的是,在计算机语言中添加某种语法,这种语法能使程序员更方便的使用语言开发程序,同时增强程序代码的可读性,避免出错的机会;但是这种语法对语言的功能并没有影响。
Java中的泛型,变长参数,自动拆箱/装箱,条件编译等都是,下面做简单的介绍和分析。


泛型
与C#中的泛型相比,Java的泛型可以算是“伪泛型”了。在C#中,不论是在程序源码中、在编译后的中间语言,还是在运行期泛型都是真实存在的。Java则不同,Java的泛型只在源代码存在,只供编辑器检查使用,编译后的字节码文件已擦除了泛型类型,同时在必要的地方插入了强制转型的代码。
泛型代码:

 

public static void main(String[] args) {
    List<String> stringList = new ArrayList<String>();
    stringList.add("oliver");
    System.out.println(stringList.get(0));
}
 

 

将上面的代码的字节码反编译后:
public static void main(String args[])
{
    List stringList = new ArrayList();
    stringList.add("oliver");
    System.out.println((String)stringList.get(0));
}
 

自动拆箱/装箱
自动拆箱/装箱是在编译期,依据代码的语法,决定是否进行拆箱和装箱动作。
装箱过程:把基本类型用它们对应的包装类型进行包装,使基本类型具有对象特征。
拆箱过程:与装箱过程相反,把包装类型转换成基本类型。
需要注意的是:包装类型的“==”运算在没有遇到算数运算符的情况下不会自动拆箱,而其包装类型的equals()方法不会处理数据类型转换,所以:
Integer a = 1;
Integer b = 1;
Long c = 1L;
System.out.println(a == b);
System.out.println(c.equals(a));
 
这样的代码应该尽量避免自动拆箱与装箱。

循环历遍(foreach)
语法:
List<Integer> list = new ArrayList<Integer>();
for(Integer num : list){
    System.out.println(num);
}
 
Foreach要求被历遍的对象要实现Iterable接口,由此可想而知,foreach迭代也是调用底层的迭代器实现的。反编译上面源码的字节码:
List list = new ArrayList();
Integer num;
Integer num;
for (Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(num)){
    num = (Integer) iterator.next();
}
 
条件编辑
很多编程语言都提供了条件编译的途径,C,C++中使用#ifdef。Java语言并没有提供这种预编译功能,但是Java也能实现预编译。
if(true){
    System.out.println("oliver");
}else{
    System.out.println("lee");
}
 
这段代码的字节码反编译后只有一条语句:
System.out.println("oliver");
 
在编译器中,将会把分支不成立的代码消除,这一动作发生在编译器解除语法糖阶段。
所以说,可以利用条件语句来实现预编译。

枚举
枚举类型其实并不复杂,在JVM字节码文件结构中,并没有“枚举”这个类型。
其实源程序的枚举类型,会在编译期被编译成一个普通了类。利用继承和反射,这是完全可以做到的。
看下面一个枚举类:
public enum EnumTest {
    OLIVER,LEE;
}
 
反编译字节码后:
public final class EnumTest extends Enum {
	private EnumTest(String s, int i) {
		super(s, i);
	}
	public static EnumTest[] values() {
		EnumTest aenumtest[];
		int i;
		EnumTest aenumtest1[];
		System.arraycopy(aenumtest = ENUM$VALUES, 0,
				aenumtest1 = new EnumTest[i = aenumtest.length], 0, i);
		return aenumtest1;
	}
	public static EnumTest valueOf(String s) {
		return (EnumTest) Enum.valueOf(EnumTest, s);
	}
	public static final EnumTest OLIVER;
	public static final EnumTest LEE;
	private static final EnumTest ENUM$VALUES[];
	static {
		OLIVER = new EnumTest("OLIVER", 0);
		LEE = new EnumTest("LEE", 1);
		ENUM$VALUES = (new EnumTest[] { OLIVER, LEE });
	}
}
 
至于更多细节,可以参考父类Enum。

变长参数
变长参数允许我们传入到方法的参数是不固定个数。
对于这个方法:
public void foo(String str,Object...args){
}
 
我们可以这样调用:
foo("oliver");
foo("oliver",new Object());
foo("oliver",new Integer(1),"sss");
foo("oliver",new ArrayList(),new Object(),true,1);
 
参数args可以是任意多个。
其实,在编译阶段,args是会被编译成Object [] args。
public transient void foo(String s, Object aobj[])
{
}
 
这样,变长参数就可以实现了。
但是要注意的是,变长参数必须是方法参数的最后一项。

除了上面介绍的语法糖,还有内部类,断言以及JDK7的switch支持字符串,自动关闭资源(在try中定义和关闭)等。
感兴趣的同学可以反编译字节码了解它们的本质。
无疑,语法糖方便了程序员的开发,提高了开发效率,提升了语法的严谨也减少了编码出错误的几率。我们不仅仅在平时的编码中依赖语法糖,更要看清语法糖背后程序代码的真实结构,这样才能更好的利用它们。


 

分享到:
评论

相关推荐

    Java中的语法糖.docx

    语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的 某种语法 ,这种语法对语言本身的功能来说没有什么影响,只是为了方便程序员进行开发,提高开发效率,使用这种语法写出来的程序可读性也更高。...

    C#语法糖(Csharp Syntactic sugar)大汇总

    首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。这让java开发人员羡慕不已,呵呵。

    C#的自定义语法糖的使用详解

    语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。...

    Objective-C中的语法糖示例详解

    语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。 ...

    Go语法糖之‘...’ 的使用实例详解

    语法糖(Syntactic sugar),也译为糖衣语法,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。这篇文章主要给大家介绍Go语法糖之‘...’ 的使用,感兴趣的朋友一起看看吧

    yacc.tar.Z_C- 语法分析_Syntactic analysis_yacc_yacc.tar_yacc工具

    伯克利的语法分析器的创建工具

    missilewar:Syntactic Sugar Studio 的导弹战争 HTML5 游戏

    导弹战争 旧 WC3 自定义地图的独立翻拍。 #指示 使用 WASD 平移相机。 建造发电机以获取能量。 使用能量购买筒仓和护盾助推器。 使用筒仓自动向敌人发射火箭、导弹等。 积蓄能量进行大规模攻击,然后挺过去!

    delphi语法大全(中文)

    Syntactic elements(语法元素) Syntactic elements: Overview(概述) Object Pascal 使用ASCII 字符集,包括A 到Z、a 到z、0 到9、...表达式是一个语法单元,它出现在命令语句中并表示一个值;声明定义 一个标志符

    句法多样化专题 (Syntactic Variety).doc

    句法多样化专题 (Syntactic Variety) 1. 并列 a) 并列大量名词: n1, n2, n3, …, and nn i. A, B, C, … and other Xs… ii. X, such [Y] as A, B, C…, … b) 并列名词性成份: n. + what/how/whether/if… [并列...

    Syntactic Pattern Recognition of the ECG.pdf

    An application of the syntactic method to recognition of electrocardiogram (ECG) and to the measurement of ECG parameters is presented. Solutions to the subproblems of primitive pattern selection, ...

    Lexical-and-Syntactic-Analysis-Toy:词法分析和语法分析的联系

    词法和语法分析的练习程序 词法分析部分通过配置文件中的正则表达式, 去构建自动机, 依次来进行词法分析。 ...语法分析中遇到错误时, 会立即报错, 并退出程序。 如果无错误, 则返回 success。

    Learning syntactic patterns for automatic hypernym discovery

    syntactic patterns for automatic hypernym discovery Semantic taxonomies such as WordNet provide a rich source of knowledge for natural language processing applications, but are expensive to build, ...

    MoyaSugar:for Moya的语法糖

    莫亚糖 Moya的语法糖。为什么? 是一个优雅的网络抽象层,它通过enum优雅地抽象API端点。 但是,当应用程序变大时,它将变得庞大。 无论何时添加端点,都应至少在5个地方编写代码:枚举大小写, method , path , ...

    java的类别方法(格式:PPT 字体:繁体)

    程序的「语法」(Syntactic)是说明程序需要传入何种资料型态的「参数」(Parameters)和传回值. 「语意」(Semantic)是指出这个程序可以作什麼事 在撰写程序时,我们需要了解程序的语法规则,在使用程序时需要了解程序的...

    syntactic-sugar-sequence:SER215 项目

    句法-糖-序列SER215 项目请记住(尤其是在打开项目时): 拉代码犯罪利润重复“松唇沉船!” “不拉就不要编码!” “离开枪,拿走奶油卷。”

    java笔试题算法-Syntactic:用于大型数据集的词法分类引擎。适用于NLP和数据挖掘

    java笔试题算法句法 建造 54 奥马尔·夏皮拉 可视化: 接受贡献者! 阅读“问题”列表中的当前任务并加入。如果有任何问题,请随时通过 info∞omershapiraºcom 与我联系。 描述 Syntactic 是一个程序,可以读取大量...

    SyntacticAnalyzer语法分析器设计报告.doc

    SyntacticAnalyzer语法分析器设计报告.doc

    [Mock框架] NMock3 3.5.44.0

    The idea of Syntactic Sugar is maintained in that all expectations read like an English sentence; ☆ 文件清单:☆ NMock3 NetFx 3.5 v3.5.44.0 NMock3 NetFx 4.0 v3.5.44.0 ☆ 相关网址:☆ NMock3 ...

Global site tag (gtag.js) - Google Analytics