基础---java 中的语法糖

一、定义

       什么叫语法糖?顾名思义,我的理解是,编程语言给程序员提供的一些个便利的操作,在保证性能的基础上提高开发效率。

帖一下百度百科解释: 语法糖(Syntactic sugar),是由Peter J. Landin(和图灵一样的天才人物,是他最先发现了Lambda演算,由此而创立了函数式编程)创造的一个词语,它意指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜”的语法。语法糖往往给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读。不过其并没有给语言添加什么新东西。

二、java语言中的语法糖

Java中的语法糖包括但不限于以下10颗:泛型与类型擦除、自动装箱和拆箱、遍历循环、变长参数、条件编译、内部类、枚举类、断言语句、对枚举和字符串的switch支持、在try语句中定义和关闭资源。

1、泛型与类型擦除,前面博文中有介绍,java的泛型是伪泛型,在编译的时候进行擦除。

2、自动装箱和拆箱,前面博文中也有,Java基本数据类型都有封装类型,Integer i=100,就是自动装箱,int j = i,就是自动拆箱,如果int k = 100,先装箱后拆箱。特殊性就是在-128~127之间的整数,Integer可以缓存,重用。

3、foreach循环遍历

List list = new ArrayList();
for(Object object:list){
...
}
或者
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();
}
4、条件编译
if(true){  
    System.out.println("oliver");  
}else{  
    System.out.println("lee");  
}  
编译后只有System.out.println("oliver");在编译器中,将会把分支不成立的代码消除,这一动作发生在编译器解除语法糖阶段。所以说,可以利用条件语句来实现预编译
5、枚举
啊...原来枚举是一块糖啊,记得前段时间,加的一个java群里面的人讨论枚举类型,到底是数据类型还是类?当时很是迷惑...查看java api如下:
public abstract class Enum<E extends Enum<E>>extends Objectimplements Comparable<E>, Serializable
java doc上说它是一个所有 Java 语言枚举类型的公共基本类。
枚举类型其实并不复杂,在JVM字节码文件结构中,并没有“枚举”这个类型。
其实源程序的枚举类型,会在编译期被编译成一个普通了类。利用继承和反射,这是完全可以做到的。
看下面一个枚举类:
public enum TestEnum {
	A,B
}
反编译之后会怎样?(jad.exe -s java xx.class)
public final class TestEnum extends Enum
{

    private TestEnum(String s, int i)
    {
        super(s, i);
    }

    public static TestEnum[] values()
    {
        TestEnum atestenum[];
        int i;
        TestEnum atestenum1[];
        System.arraycopy(atestenum = ENUM$VALUES, 0, atestenum1 = new TestEnum[i = atestenum.length], 0, i);
        return atestenum1;
    }

    public static TestEnum valueOf(String s)
    {
        return (TestEnum)Enum.valueOf(javaTest/TestEnum, s);
    }

    public static final TestEnum A;
    public static final TestEnum B;
    private static final TestEnum ENUM$VALUES[];

    static 
    {
        A = new TestEnum("A", 0);
        B = new TestEnum("B", 1);
        ENUM$VALUES = (new TestEnum[] {
            A, B
        });
    }
}

可见,字节码中已经被改成类的的实现了。

通过以上分析,java枚举是一个类,不是语言本身实现的,而是编译器实现的,我们可以直接调用里面的方法。Enum 本身就是个普通的 class, 可以有很多自定义方法用来实现不同的功能。如果我们不自定义里面的方法,编译器就能初始化,默认顺序从0递增。我们也可以自定义方法,这样就能随便赋值。

public enum TestEnum {
	A(1),B(2);
	private final int value;
	public int getValue(){
		return this.value;
	}
	TestEnum(int value){
		this.value=value;
	}
}


6、变长参数
上代码
public void function(String...arg){
		
}
反编译之后,还是用jad来做
public transient void function(String as[])
{
}
参数变成了String数组,但是要注意的是,变长参数必须是方法参数的最后一项。
例如:
public void function(int abc, String...arg){

 }
7、内部类
内部类:成员内部类(类中定义),静态内部类(加上static),局部内部类(在方法内),匿名类,接口类,具体详细介绍后面会写博文学习
这里看两个简单的:普通的内部类和静态内部类
public class InnerClass {
	private int OUT;
	
	class InnerA{
		private int A;
	}
	
	static class InnerB{
		private int B;
	}
	
}
反编译之后
public class InnerClass
{
    class InnerA
    {

        private int A;
        final InnerClass this$0;

        InnerA()
        {
            this$0 = InnerClass.this;
            super();
        }
    }

    static class InnerB
    {

        private int B;

        InnerB()
        {
        }
    }


    public InnerClass()
    {
    }

    private int OUT;
}
发现InnerA中编译器给加上了外部内的一个引用,让其访问外部资源。静态内部类没加,而且发现InnerA要实例化的时候需要调用super(),也就是需要外部类的实力,静态内部类就不需要,直接用类名就可以。这里编译器给的糖是给普通内部类代码中添加了些代码。
8、断言语句
略过...
9、对枚举和字符串的switch支持
利用枚举的那个类,写一个switch
               TestEnum te = null;
		switch(te){
			case A:
				System.out.println("A");
				break;
			case B:
				System.out.println("B");
				break;
			default:
				System.out.println("Null");
		}
还是反编译一下看看呗。
 public static void main(String args[])
    {
        TestEnum te = null;
        switch($SWITCH_TABLE$javaTest$TestEnum()[te.ordinal()])
        {
        case 1: // '\001'
            System.out.println("A");
            break;

        case 2: // '\002'
            System.out.println("B");
            break;

        default:
            System.out.println("Null");
            break;
        }
    }

    static int[] $SWITCH_TABLE$javaTest$TestEnum()
    {
        $SWITCH_TABLE$javaTest$TestEnum;
        if($SWITCH_TABLE$javaTest$TestEnum == null) goto _L2; else goto _L1
_L1:
        return;
_L2:
        JVM INSTR pop ;
        int ai[] = new int[TestEnum.values().length];
        try
        {
            ai[TestEnum.A.ordinal()] = 1;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[TestEnum.B.ordinal()] = 2;
        }
        catch(NoSuchFieldError _ex) { }
        return $SWITCH_TABLE$javaTest$TestEnum = ai;
    }

    private static int $SWITCH_TABLE$javaTest$TestEnum[];
呀呀呀,看看都什么变化。。。这个糖变化最大。。。
重点是case后面跟的是整型,说明switch的糖就是貌似可以支持枚举,但是还是利用的枚举中的成员的初始化值。

在来看一个字符串的switch
public static void main(String[] args) {
		String abc="";
		switch(abc){
			case "A":
				System.out.println("A");
				break;
			case "B":
				System.out.println("B");
				break;
			default:
				System.out.println("Null");
		}
					
	}
反编译之后
 public static void main(String args[])
    {
label0:
        {
            String abc = "";
            String s;
            switch((s = abc).hashCode())
            {
            default:
                break;

            case 65: // 'A'
                if(s.equals("A"))
                {
                    System.out.println("A");
                    break label0;
                }
                break;

            case 66: // 'B'
                if(!s.equals("B"))
                    break;
                System.out.println("B");
                break label0;
            }
            System.out.println("Null");
        }
    }
其实就是比较的字符串的hashcode。
10、在try语句中定义和关闭资源jdk7提供了try-with-resources,可以自动关闭相关的资源(只要该资源实现了AutoCloseable接口,jdk7为绝大部分资源对象都实现了这个接口)
Java7增强了try语句的功能,它允许在try关键字后紧跟一对圆括号,圆括号可以声明、初始化一个或多个资源(此处的资源是指那些必须在程序结束时显式关闭的资源,比如数据库连接,网络连接等),try-with-resources 是一个定义了一个或多个资源的try 声明,try语句在该语句结束时自动关闭这些资源。try-with-resources确保每一个资源在处理完成后都会被关闭。
上代码
public static void main(String[] args) {
		try (
	        // 声明、初始化两个可关闭的资源
			BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));
			PrintStream ps = new PrintStream(new FileOutputStream("readme.txt"))
			){
			// 使用两个资源
			System.out.println(br.readLine());
			ps.println("test");
		}catch(Exception e){
			e.printStackTrace();
		}
		// 自动关闭资源的try语句相当于包含了隐式的finally块,用于关闭资源。
反编译看看
 public static void main(String args[])
    {
        Exception exception;
        exception = null;
        Object obj = null;
        BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));
        PrintStream ps = new PrintStream(new FileOutputStream("readme.txt"));
        System.out.println(br.readLine());
        ps.println("test");
        if(ps != null)
            ps.close();
        break MISSING_BLOCK_LABEL_82;
        exception;
        if(ps != null)
            ps.close();
        throw exception;
        if(br != null)
            br.close();
        break MISSING_BLOCK_LABEL_150;
        Exception exception1;
        exception1;
        if(exception == null)
            exception = exception1;
        else
        if(exception != exception1)
            exception.addSuppressed(exception1);
        if(br != null)
            br.close();
        throw exception;
        exception1;
        if(exception == null)
            exception = exception1;
        else
        if(exception != exception1)
            exception.addSuppressed(exception1);
        throw exception;
        Exception e;
        e;
        e.printStackTrace();
    }
很明显了,给全部关掉了,但是貌似java7这个功能,我还没有用到,先学习吧。











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值