public class Test { // No throws clause here public static void main(String[] args) { doThrow(new SQLException()); } static void doThrow(Exception e) { Test.
doThrow0(e); } @SuppressWarnings("unchecked") static
void doThrow0(Exception e) throws E { throw (E) e; } }
class Test { Object x() { return "abc"; } String x() { return "123"; } }
bener. Basa Jawa ora ngidini rong cara bisa diganti kanthi padha ing kelas sing padha ing wektu sing padha, ora preduli saka bedane ing jinis lemparan utawa bali. Nanging ngenteni sedhela. Priksa dokumentasi maneh kanggo Class.getMethod(String, Class…). Iku ngandika:
Elinga yen ana luwih saka siji cara sing cocog ing kelas, amarga nalika basa Jawa nglarang macem-macem cara karo teken padha nanging jinis bali beda, Jawa Virtual Machine ora. Keluwesan ing mesin virtual iki bisa digunakake kanggo ngetrapake macem-macem fitur basa. Contone, ngasilake kovarian bisa ditindakake kanthi metode jembatan; Cara jembatan lan metode sing ditimpa bakal duwe tandha sing padha nanging jinis bali sing beda. Wow, sing nggawe akal. Ana sing bener cukup akeh nalika sampeyan nulis ing ngisor iki: Deleng ing bytecode kui: Dadi t bener obyek ing bytecode. Iki uga dimangerteni. Cara bridge tiron bener kui dening compiler amarga jinis bali saka Parent.x () bisa samesthine ing bagean tartamtu saka telpon. Nambahake generik tanpa metode jembatan kasebut ora bakal bisa ditindakake maneh ing perwakilan binar. Dadi, ngganti JVM kanggo ngidini fitur kuwi diprodhuksi kurang pain (sing uga ngidini cara kovarian overriding minangka efek sisih ...) Smart tengen?
3. Kabeh ing ngisor iki minangka susunan rong dimensi. Iki bener bener. Sanajan analisa mental sampeyan ora bisa langsung ngerti jinis bali saka cara sing diterangake ing ndhuwur, kabeh padha! Kaya potongan kode sabanjure. Apa sampeyan mikir iki edan? Jumlah kesempatan kanggo nulis uga mung njeblug imajinasi!
Ketik anotasi.
Piranti sing misteri sing nomer loro mung kekuwatane. Utawa kanthi tembung liya: Nalika aku nggawe komitmen pungkasan sadurunge preian 4 minggu. Aku menehi idin kanggo nggunakake ing sembarang cara sing disenengi.
4. Sampeyan ora bakal entuk kondisional Dadi, sampeyan mikir sampeyan wis ngerti kabeh babagan syarat nalika sampeyan miwiti nggunakake? Ayo kula nguciwani sampeyan - sampeyan salah. Umume sampeyan bakal mikir yen rong conto ing ngisor iki padha karo: padha karo iki? Ora. Ayo nggunakake tes cepet Program bakal ngasilake ing ngisor iki: Ya! Operator kondisional bakal nindakake jinis cast yen perlu. Amarga yen ora, sampeyan bakal nyana program uncalan NullPointerException?
5. Sampeyan uga ora bakal njaluk operator assignment senyawa. Apa daya cukup? Ayo deleng rong potongan kode ing ngisor iki:
abstract class Parent
{ abstract T x(); } class Child extends Parent
{ @Override String x() { return "abc"; } }
// Method descriptor #15 ()Ljava/lang/String; // Stack: 1, Locals: 1 java.lang.String x(); 0 ldc
[16] 2 areturn Line 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: 1 bridge synthetic java.lang.Object x(); 0 aload_0 [this] 1 invokevirtual Child.x() : java.lang.String [19] 4 areturn Line numbers: [pc: 0, line: 1]
class Test { int[][] a() { return new int[0][]; } int[] b() [] { return new int[0][]; } int c() [][] { return new int[0][]; } }
class Test { int[][] a = {{}}; int[] b[] = {{}}; int c[][] = {{}}; }
@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 [] = {{}}; }
Object o1 = true ? new Integer(1) : new Double(2.0);
Object o2; if (true) o2 = new Integer(1); else o2 = new Double(2.0);
System.out.println(o1); System.out.println(o2);
1.0 1
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);
i += j; i = i + j;
Intuisi, padha kudu padha tengen? Nanging sampeyan ngerti apa - padha beda. Spesifikasi JLS ngandika:
A expression senyawa saka jinis E1 op = E2 padha karo E1 = (T) ((E1) op (E2)), ngendi T iku jinis E1, kajaba sing E1 dievaluasi mung sapisan. Conto sing apik yaiku nggunakake *= utawa /= :
byte b = 10; b *= 5.7; System.out.println(b); // prints 57
utawa:
byte b = 100; b /= 2.5; System.out.println(b); // prints 40
utawa:
char ch = '0'; ch *= 1.1; System.out.println(ch); // prints '4'
utawa:
char ch = 'A'; ch *= 1.5; System.out.println(ch); // prints 'a'
Dadi, apa iki isih alat sing migunani?
6. Integer acak Saiki kanggo tugas sing luwih angel. Aja maca solusi. Delengen yen sampeyan bisa nemokake jawaban dhewe. Nalika aku mbukak program ing ngisor iki:
for (int i = 0; i < 10; i++) { System.out.println((Integer) i); }
Kadang aku njaluk output ing ngisor iki:
92 221 45 48 236 183 39 193 33 84
Nanging carane iki malah bisa? Ok, jawabane dumunung ing overriding cache Integer JDK liwat refleksi, banjur nggunakake auto-boxing lan auto-unboxing. Aja nindakake iki tanpa ijin wong diwasa! Utawa kanthi tembung liya:
7. GOTO Salah sawijining favoritku. Jawa wis GOTO! Tulis iki:
int goto = 1;
lan sampeyan entuk iki: Iku amarga goto minangka tembung sing ora digunakake, yen ora ... Nanging dudu bagean sing nyenengake. Sing apik yaiku sampeyan bisa nyakup goto sing dipasangake karo blok break, continue lan ditandhani: Mlumpat maju Ing kode bait: Mlumpat mundur Ing kode bait:
8. Jawa nduweni jeneng alias Ing basa liya (kaya Ceylon), kita bisa nemtokake jinis. alias gampang banget: Kelas Wong ing kene dibangun kanthi cara sing bisa diijolake karo Set
Test.java:44: error:
expected int goto = 1; ^
label: { // do stuff if (check) break label; // do more stuff }
2 iload_1 [check] 3 ifeq 6 // Jumping forward 6 ..
label: do { // do stuff if (check) continue label; // do more stuff break label; } while(true);
2 iload_1 [check] 3 ifeq 9 6 goto 2 // Jumping backward 9 ..
interface People => Set
;
People? p1 = null; Set
? p2 = p1; People? p3 = p2;
class Test {
void x(I i, L l) { System.out.println( i.intValue() + ", " + l.longValue() ); } }
new Test().x(1, 2L);
// A helper type. You could also just use List interface Type
{} class C implements Type
> {} class D
implements Type
Dadi apa tegese C lan D? Ing pangertèn padha rekursif, padha rekursi ing java.lang.Enum. Coba: Given specifications ndhuwur, implementasine nyata saka enum mung gula sintaksis: Kanthi atine, ayo bali menyang rong jinis kita. Apa kode ing ngisor iki bakal dikompilasi? Pitakonan sing angel ... lan ora dirampungake? Apa C minangka subtipe saka Tipe ? Coba kompilasi iki ing Eclipse utawa Idea sampeyan lan dheweke bakal ngandhani apa sing dikira. Siram mudhun saluran ... Sawetara jinis sesambetan ing Jawa undecidable! 10. Tipe Intersection Jawa nduweni fitur sing menarik banget yaiku tipe intersection. Sampeyan bisa ngumumake jinis (generik) sing sejatine persimpangan saka rong jinis. Contone: Parameter tipe khusus T sing digandhengake karo conto kelas Test kudu kalebu antarmuka Serializable lan Cloneable. Contone, String ora bisa diwatesi, nanging Tanggal bisa: Fitur iki wis sawetara nggunakake ing Java8, ngendi sampeyan bisa cast jinis. Kepiye carane iki mbantu? Meh ora ana, nanging yen sampeyan pengin nggawe ekspresi lambda menyang jinis sing sampeyan butuhake, mula ora ana cara liya. Ayo dadi ngomong sampeyan duwe watesan edan ing cara sampeyan: Sampeyan pengin Runnable sing ing wektu sing padha Serializable mung yen sampeyan pengin nglakokaké ing panggonan liya lan ngirim asil liwat jaringan. Lambda lan serialisasi nambahake ironi. Sampeyan bisa nggawe serialisasi ekspresi lambda yen jinis target lan argumentasi bisa disambungake. Nanging sanajan iki bener, padha ora ngaktifake antarmuka Serializable kanthi otomatis. Sampeyan kudu nggawa dhewe menyang jinis iki. Nanging nalika sampeyan mung matak Serializable: banjur lambda ora bakal Runnable maneh, supaya matak kanggo loro jinis: Lan ing kesimpulan: public abstract class Enum
// This enum MyEnum {} // Is really just sugar for this class MyEnum extends Enum
class Test { Type c = new C(); Type> d = new D
Step 0) C Step 1) Type
>> > Step 4) D
class Test
// Doesn't compile Test
execute((Serializable) (() -> {}));
execute((Runnable & Serializable) (() -> {}));
GO TO FULL VERSION