关于java:Java里的奇技淫巧

16次阅读

共计 3258 个字符,预计需要花费 9 分钟才能阅读完成。

Java是一种宽泛应用的计算机编程语言、面向对象、泛型编程的个性,广泛应用于企业级 Web 利用开发和挪动利用开发。

1995 年 3 月 23 日 Sun 公司公布了Java,至今已有近 26 年,能够说是一门非常成熟的开发语言了,但在某些鲜为人知的中央存在着一些意料之外的个性。

Java 的保留关键字 goto 和 const

Java 外面没有 goto 这个性能,但它作为保留字是无奈当做变量来应用的,const也是同样。

int goto = 0;
int const = 0;

下面这两行代码的写法存在问题,无奈失常编译通过。

Java 标签 Label

下面说了在 Java 外面没有 goto 这个性能,但为了解决多重循环引入了 Label,目标是为了在多重循环中不便的应用 break 和 coutinue,但如同在其余中央也能够用。

outerLoop:
while (true) {System.out.println("I'm the outer loop");
    int i = 0;
    while (true) {System.out.println("I am the inner loop");
        i++;
        if (i >= 3) {break outerLoop;}
    }
}
System.out.println("Complete the loop");

// 输入
I'm the outer loop
I am the inner loop
I am the inner loop
I am the inner loop
Complete the loop
test:
{System.out.println("hello");
    if (true) {break test; // works}
  System.out.println("world");
}

// 输入
hello
test:
if (true) {System.out.println("hello");
    if (true) {break test; // works}
    System.out.println("world");
}
// 输入
hello
test:
try {System.out.println("hello");
    if (true) {break test; // works}
    System.out.println("world");
} finally {
}
// 输入
hello

Integer 的是否相等问题

日常开发应用到 Java 根本数据类型是不可避免的一件事,但它却蕴含了一些很容易犯错的点,踩过一些坑的同学可能理解 Java 根本包装类型的常量池技术,例如 Integer 就具备数值 [-128,127] 的相应类型的缓存数据,但上面定义的 4 个变量是否相等你是否能说的进去呢?

Integer i1 = 127;
Integer i2 = Integer.valueOf(127);
Integer i3 = Integer.parseInt("127");

Integer i4 = new Integer(127);

System.out.println(i1 == i2);
// true
System.out.println(i1 == i3);
// true
System.out.println(i2 == i3);
// true

System.out.println(i4 == i1);
// false
System.out.println(i4 == i2);
// false
System.out.println(i4 == i3);
// false
  1. Integer i1 = 127; Java 在编译的时候会间接将代码优化为 Integer i1=Integer.valueOf(127);,从而应用常量池中的对象。
  2. Integer i2 = Integer.valueOf(127); 会从 Integer 缓存中获取。

    Integer.valueOf源码如下。

    /**
     * 会从缓存数组中获取范畴为 [-128, 127] 的值,如果没有就创立一个新的对象。*/
    public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
  3. Integer.parseInt("127"); 返回值是 int 数字,在 [-128, 127] 范畴的会从常量池中获取。
  4. new Integer(127); 创立一个新的对象。

Integer 对象的缓存值的大小范畴是在 [-128 127] 区间。这意味着当咱们在此数值范畴内操作时,“==”比拟能失常返回后果。但当数值不在此范畴,对象相等的比拟是否失常返回后果就很难说了。所以为了平安,在应用对象数值进行比拟相等时,请应用 “.equals()”,而不是依赖于“==” 比拟相等,除非你十分必定这种做法没有谬误。

思考一个问题,当变量的数值均为 128 时会输入什么后果呢?

Double.MIN_VALUE 居然不是正数?

咱们可能是受了太多 IntegerLong的影响,天经地义的认为 Double.MIN_VALUE 应该是一个正数,但实际上 Double.MIN_VALUE 是非 0 非负的最小值 4.9E-324Float 也是同样。如果你想要最小的 Double 类型的数字,请应用-Double.MAX_VALUE

System.out.println(Double.MAX_VALUE);
// 1.7976931348623157E308
System.out.println(Double.MIN_VALUE);
// 4.9E-324
System.out.println(Float.MAX_VALUE);
// 3.4028235E38
System.out.println(Float.MIN_VALUE);
// 1.4E-45

应用 for 做死循环?

提到死循环大家都会想到 while(true),但还有另一种写法 for(;;),在字节码层面他们会被编译为同样的内容,一些上古C/C++ 程序员写 Java 的时候还会应用 for(;;) 做死循环,遇到这样的敌人肯定要珍惜哦。

while (true){// do something}
for(;;){// do something}

下划线也能当做变量?

Object _ = new Object();
System.out.println(_.toString());

在 Java8 中还能应用下划线当做变量,但在 Java9 之后就标记为不再反对,请珍惜和它的最初这段时光吧。

WTF!!! finally 还能返回内容?

public class Finally {public int fun() {
        try {return 0;} finally {return 1;}
    }

    public static void main(String[] args) {Finally aFinally = new Finally();
        System.out.println(aFinally.fun());
          // 1
    }
}

面试的时候 finally 返回值坑了多少英雄好汉?

一个类能够有几个 static 代码块?

public class Static {

    static {System.out.println("hello");
    }

    static {System.out.println("world");
    }

    static {System.out.println("java");
    }

    public static void main(String[] args) {}}

// 输入
hello
world
java

Java????????

final 类型肯定要申明的时候进行初始化吗?

对于 final 类型的变量不可批改是每一个 Java 开发的常识,申明变量的时候就要对其进行初始化,但真的是这样的吗?

public class Final {public static void main(String[] args) {
        final int a;
        if (args != null) {a = 0;} else {a = 1;}
        System.out.println(a);
        // 0 
    }
}

是否有点违反认知了?

正文完
 0