日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java多线程做一件事_关于Java的十件事

發(fā)布時(shí)間:2023/12/3 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java多线程做一件事_关于Java的十件事 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java多線程做一件事

那么,您從一開始就一直在使用Java? 還記得那些被稱為“ Oak”的日子,OO仍然是熱門話題,C ++人士認(rèn)為Java沒有機(jī)會(huì),Applet還是一件事嗎?

我敢打賭,您至少不了解以下一半內(nèi)容。 讓我們從本周開始,對(duì)Java的內(nèi)部運(yùn)作產(chǎn)生一些驚喜。

1.沒有被檢查的異常

那就對(duì)了! JVM不知道任何這樣的事情,只有Java語言知道。

今天,每個(gè)人都同意檢查異常是一個(gè)錯(cuò)誤。 正如Bruce Eckel在布拉格GeeCON閉幕致辭中所說的那樣,在Java參與使用受檢查的異常之后,沒有其他語言可以使用,甚至Java 8也不再將它們包含在新的Streams API中( 這可能有些痛苦,當(dāng)您的lambda使用IO或JDBC時(shí) )。

您是否想要證明JVM不知道這樣的事情? 嘗試以下代碼:

public class Test {// No throws clause herepublic static void main(String[] args) {doThrow(new SQLException());}static void doThrow(Exception e) {Test.<RuntimeException> doThrow0(e);}@SuppressWarnings("unchecked")static <E extends Exception> void doThrow0(Exception e) throws E {throw (E) e;} }

這不僅會(huì)編譯,而且實(shí)際上還會(huì)引發(fā)SQLException ,您甚至不需要Lombok的@SneakyThrows 。

  • 關(guān)于以上內(nèi)容的更多詳細(xì)信息,可以在本文中或此處的Stack Overflow上找到 。

2.您可以使方法重載僅在返回類型上有所不同

那不會(huì)編譯,對(duì)嗎?

class Test {Object x() { return "abc"; }String x() { return "123"; } }

對(duì)。 Java語言不允許在同一個(gè)類中將兩個(gè)方法“替代等效” ,無論它們的throws子句或return類型可能如何不同。

但是請(qǐng)稍等。 Class.getMethod(String, Class...)出Class.getMethod(String, Class...)的Javadoc。 內(nèi)容為:

請(qǐng)注意,一個(gè)類中可能有多個(gè)匹配方法,因?yàn)镴ava語言禁止一個(gè)類聲明具有相同簽名但返回類型不同的多個(gè)方法,而Java虛擬機(jī)卻沒有。 虛擬機(jī)中這種增加的靈活性可用于實(shí)現(xiàn)各種語言功能。 例如,協(xié)變收益可以通過橋接方法實(shí)現(xiàn); bridge方法和被重寫的方法將具有相同的簽名,但返回類型不同。

哇,是的,這很有意義。 實(shí)際上,這幾乎就是您編寫以下內(nèi)容時(shí)發(fā)生的情況:

abstract class Parent<T> {abstract T x(); }class Child extends Parent<String> {@OverrideString x() { return "abc"; } }

在Child檢查生成的字節(jié)碼:

// Method descriptor #15 ()Ljava/lang/String;// Stack: 1, Locals: 1java.lang.String x();0 ldc <String "abc"> [16]2 areturnLine numbers:[pc: 0, line: 7]Local variable table:[pc: 0, pc: 3] local: this index: 0 type: Child// Method descriptor #18 ()Ljava/lang/Object;// Stack: 1, Locals: 1bridge synthetic java.lang.Object x();0 aload_0 [this]1 invokevirtual Child.x() : java.lang.String [19]4 areturnLine numbers:[pc: 0, line: 1]

因此, T實(shí)際上只是字節(jié)碼中的Object 。 很好理解。

合成橋方法實(shí)際上是由編譯器生成的,因?yàn)樵谀承┱{(diào)用位置可能期望Parent.x()簽名的返回類型為Object 。 如果沒有這種橋接方法,則以二進(jìn)制兼容的方式添加泛型是不可能的。 因此,更改JVM以使其具有此功能的痛苦就較小(這也使協(xié)變量重載成為副作用……)聰明吧?

您是否熟悉語言細(xì)節(jié)和內(nèi)部知識(shí)? 然后在這里找到一些更有趣的細(xì)節(jié) 。

3.所有這些都是二維數(shù)組!

class Test {int[][] a() { return new int[0][]; }int[] b() [] { return new int[0][]; }int c() [][] { return new int[0][]; } }

對(duì),是真的。 即使您的心理分析器可能無法立即理解上述方法的返回類型,它們也是相同的! 類似于以下代碼:

class Test {int[][] a = {{}};int[] b[] = {{}};int c[][] = {{}}; }

你覺得這很瘋狂嗎? 想象一下在上面使用JSR-308 / Java 8類型注釋 。 句法可能性的數(shù)量激增!

@Target(ElementType.TYPE_USE) @interface Crazy {}class Test {@Crazy int[][] a1 = {{}};int @Crazy [][] a2 = {{}};int[] @Crazy [] a3 = {{}};@Crazy int[] b1[] = {{}};int @Crazy [] b2[] = {{}};int[] b3 @Crazy [] = {{}};@Crazy int c1[][] = {{}};int c2 @Crazy [][] = {{}};int c3[] @Crazy [] = {{}}; }

輸入注釋。 僅憑其力量超越神秘感的設(shè)備

換句話說:

當(dāng)我這樣做時(shí),我的四周假期前的最后一次提交

我將為您找到上述任何一個(gè)用例的實(shí)際練習(xí)。

4.您沒有條件表達(dá)式

因此,您認(rèn)為使用條件表達(dá)式時(shí)就知道這一切嗎? 我告訴你,你沒有。 你們大多數(shù)人會(huì)認(rèn)為以下兩個(gè)片段是等效的:

Object o1 = true ? new Integer(1) : new Double(2.0);

…一樣嗎?

Object o2;if (true)o2 = new Integer(1); elseo2 = new Double(2.0);

不。 讓我們進(jìn)行快速測試

System.out.println(o1); System.out.println(o2);

該程序?qū)⒋蛴?#xff1a;

1.0 1

是的 有條件的運(yùn)營商將實(shí)現(xiàn)數(shù)字式的推廣,如果“被需要”,與認(rèn)為“需要”一個(gè)非常非常非常強(qiáng)的引號(hào)。 因?yàn)?#xff0c;您希望該程序拋出NullPointerException嗎?

Integer i = new Integer(1); if (i.equals(1))i = null; Double d = new Double(2.0); Object o = true ? i : d; // NullPointerException! System.out.println(o);
  • 有關(guān)上述內(nèi)容的更多信息,請(qǐng)參見此處 。

5.您也沒有得到復(fù)合賦值運(yùn)算符

夠古怪嗎? 讓我們考慮以下兩段代碼:

i += j; i = i + j;

憑直覺,它們應(yīng)該等效,對(duì)嗎? 但猜猜怎么了。 他們不是! JLS指定:

形式為E1 op = E2的復(fù)合賦值表達(dá)式等效于E1 =(T)(((E1)op(E2))),其中T是E1的類型,只是E1僅被評(píng)估一次。

這是如此美麗,我想引用Peter Lawrey 對(duì)這個(gè)Stack Overflow問題的回答 :

這種轉(zhuǎn)換的一個(gè)很好的例子是使用* =或/ =

byte b = 10; b *= 5.7; System.out.println(b); // prints 57

要么

byte b = 100; b /= 2.5; System.out.println(b); // prints 40

要么

char ch = '0'; ch *= 1.1; System.out.println(ch); // prints '4'

要么

char ch = 'A'; ch *= 1.5; System.out.println(ch); // prints 'a'

現(xiàn)在,這有多么有用? 我將在我的應(yīng)用程序中強(qiáng)制轉(zhuǎn)換/乘法字符。 因?yàn)?#xff0c;你知道...

6.隨機(jī)整數(shù)

現(xiàn)在,這更像是一個(gè)難題。 尚未閱讀解決方案。 看看您是否可以自己找到這個(gè)。 當(dāng)我運(yùn)行以下程序時(shí):

for (int i = 0; i < 10; i++) {System.out.println((Integer) i); }

…然后“有時(shí)”,我得到以下輸出:

92 221 45 48 236 183 39 193 33 84

這怎么可能呢??

。 擾流板...未來的解決方案...

好的,解決方案就在這里 ,它與通過反射覆蓋JDK的Integer緩存有關(guān),然后使用自動(dòng)裝箱和自動(dòng)拆箱。 不要在家做! 換句話說,讓我們?cè)龠@樣考慮一下

當(dāng)我這樣做時(shí),我的四周假期前的最后一次提交

7.轉(zhuǎn)到

這是我的最愛之一。 Java有GOTO! 輸入...

int goto = 1;

這將導(dǎo)致:

Test.java:44: error: <identifier> expectedint goto = 1;^

這是因?yàn)間oto是未使用的關(guān)鍵字 ,以防萬一……

但這不是令人興奮的部分。 令人興奮的部分是,您實(shí)際上可以使用break , continue和帶標(biāo)簽的塊來實(shí)現(xiàn)goto:

向前跳

label: {// do stuffif (check) break label;// do more stuff }

在字節(jié)碼中:

2 iload_1 [check] 3 ifeq 6 // Jumping forward 6 ..

向后跳

label: do {// do stuffif (check) continue label;// do more stuffbreak label; } while(true);

在字節(jié)碼中:

2 iload_1 [check]3 ifeq 96 goto 2 // Jumping backward9 ..

8. Java具有類型別名

在其他語言( 例如Ceylon )中,我們可以非常輕松地定義類型別名:

interface People => Set<Person>;

這樣構(gòu)造的People類型可以與Set<Person>互換使用:

People? p1 = null; Set<Person>? p2 = p1; People? p3 = p2;

在Java中,我們不能在頂級(jí)定義類型別名。 但是我們可以在類或方法的范圍內(nèi)這樣做。 讓我們考慮一下,我們對(duì)Integer , Long等的命名不滿意,我們希望使用更短的名稱: I和L 簡單:

class Test<I extends Integer> {<L extends Long> void x(I i, L l) {System.out.println(i.intValue() + ", " + l.longValue());} }

在上述程序中,對(duì)于Test類的范圍, Integer被“別名”到I ,而對(duì)于x()方法的范圍, Long被“別名”到L 然后我們可以像上面這樣調(diào)用上面的方法:

new Test().x(1, 2L);

當(dāng)然,這種技術(shù)不應(yīng)被認(rèn)真對(duì)待。 在這種情況下, Integer和Long都是最終類型,這意味著類型I和L 實(shí)際上是別名(幾乎,賦值兼容只是一種方式)。 如果我們使用了非最終類型(例如Object ),那么我們真的會(huì)使用普通的泛型。

這些愚蠢的把戲足夠了。 現(xiàn)在換個(gè)真正了不起的東西!

9.一些類型關(guān)系是不確定的!

好吧,現(xiàn)在這將變得非常時(shí)髦,因此可以喝杯咖啡并集中精力。 請(qǐng)考慮以下兩種類型:

// A helper type. You could also just use List interface Type<T> {}class C implements Type<Type<? super C>> {} class D<P> implements Type<Type<? super D<D<P>>>> {}

現(xiàn)在,類型C和D甚至意味著什么?

它們有些遞歸,以類似于java.lang.Enum遞歸的方式(但略有不同)。 考慮:

public abstract class Enum<E extends Enum<E>> { ... }

使用以上規(guī)范,實(shí)際的enum實(shí)現(xiàn)僅僅是語法糖:

// This enum MyEnum {}// Is really just sugar for this class MyEnum extends Enum<MyEnum> { ... }

考慮到這一點(diǎn),讓我們回到兩種類型。 以下內(nèi)容可以編譯嗎?

class Test {Type<? super C> c = new C();Type<? super D<Byte>> d = new D<Byte>(); }

艱苦的問題, 羅斯·泰特 ( Ross Tate)有了答案。 這個(gè)問題實(shí)際上是無法確定的:

C是Type <的子類型嗎? 超級(jí)C>?

Step 0) C <?: Type<? super C> Step 1) Type<Type<? super C>> <?: Type (inheritance) Step 2) C (checking wildcard ? super C) Step . . . (cycle forever)

然后:

D是Type <的子類型嗎? 超級(jí)D <Byte >>?

Step 0) D<Byte> <?: Type<? super C<Byte>> Step 1) Type<Type<? super D<D<Byte>>>> <?: Type<? super D<Byte>> Step 2) D<Byte> <?: Type<? super D<D<Byte>>> Step 3) List<List<? super C<C>>> <?: List<? super C<C>> Step 4) D<D<Byte>> <?: Type<? super D<D<Byte>>> Step . . . (expand forever)

嘗試在Eclipse中編譯以上代碼,它將崩潰! ( 不用擔(dān)心。我已經(jīng)提交了一個(gè)錯(cuò)誤 )

讓它沉入……

Java中的某些類型關(guān)系是不確定的 !

如果您對(duì)有關(guān)此奇特的Java怪癖的更多詳細(xì)信息感興趣,請(qǐng)閱讀Ross Tate的論文“在Java的類型系統(tǒng)中馴服通配符” (與Alan Leung和Sorin Lerner合著),或者閱讀我們自己關(guān)于將子類型多態(tài)與泛型多態(tài)相關(guān)聯(lián)的想法。

10.類型交點(diǎn)

Java具有一個(gè)非常獨(dú)特的功能,稱為類型交集。 您可以聲明一個(gè)(通用)類型,它實(shí)際上是兩種類型的交集。 例如:

class Test<T extends Serializable & Cloneable> { }

泛型類型參數(shù)T ,你綁定的類的實(shí)例Test必須實(shí)現(xiàn) Serializable和Cloneable 。 例如, String不是可能的綁定,但Date是:

// Doesn't compile Test<String> s = null;// Compiles Test<Date> d = null;

Java 8中已重用了此功能,您現(xiàn)在可以在其中將類型轉(zhuǎn)換為臨時(shí)類型的交集。 這有什么用? 幾乎沒有,但是如果您想將lambda表達(dá)式強(qiáng)制為這種類型,則別無選擇。 假設(shè)您的方法受到這種瘋狂的類型約束:

<T extends Runnable & Serializable> void execute(T t) {}

您想要一個(gè)可Serializable的Runnable ,以防您想在其他地方執(zhí)行它并通過電線發(fā)送它。 Lambda和序列化有點(diǎn)古怪。

Lambda可以序列化 :

如果lambda表達(dá)式的目標(biāo)類型和捕獲的參數(shù)可序列化,則可以對(duì)其進(jìn)行序列化

但是,即使這是真的,他們也不會(huì)自動(dòng)實(shí)現(xiàn)Serializable標(biāo)記接口。 要強(qiáng)制他們使用這種類型,必須強(qiáng)制轉(zhuǎn)換。 但是當(dāng)您只轉(zhuǎn)換為Serializable ...

execute((Serializable) (() -> {}));

…然后,lambda將不再可運(yùn)行。

嗯...

所以…

將其強(qiáng)制轉(zhuǎn)換為兩種類型:

execute((Runnable & Serializable) (() -> {}));

結(jié)論

我通常只說這是關(guān)于SQL的問題,但現(xiàn)在該是一篇包含以下內(nèi)容的文章了:

Java是僅憑其強(qiáng)大功能就無法解開謎底的設(shè)備。

翻譯自: https://www.javacodegeeks.com/2014/11/10-things-you-didnt-know-about-java.html

java多線程做一件事

總結(jié)

以上是生活随笔為你收集整理的java多线程做一件事_关于Java的十件事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。