Java sözdizimi - Java syntax

Image
Anahtar kelimelerin koyu mavi yazı tipiyle vurgulandığı bir Java kodu parçacığı

Sözdizimi ait Java atıfta kurallar kümesi bir Java programı yazılır ve nasıl yorumlandığını tanımlayan.

Sözdizimi çoğunlukla C ve C++ ' dan türetilmiştir . C++'dan farklı olarak Java'da global işlevler veya değişkenler yoktur, ancak global değişkenler olarak da kabul edilen veri üyeleri vardır . Tüm kodlar sınıflara aittir ve tüm değerler nesnelerdir . Tek istisna, performans nedenleriyle bir sınıf örneği tarafından temsil edilmeyen ilkel türlerdir (ancak otomatik olarak nesnelere dönüştürülebilir ve bunun tersi de otomatik kutulama yoluyla yapılabilir ). Operatör aşırı yüklemesi veya işaretsiz tamsayı türleri gibi bazı özellikler , dili basitleştirmek ve olası programlama hatalarını önlemek için atlanmıştır.

Java sözdizimi, sayısız büyük JDK yayınları sırasında kademeli olarak genişletildi ve şimdi genel programlama ve işlev değişmezleri (Java'da lambda ifadeleri olarak adlandırılır) gibi yetenekleri destekliyor . 2017'den bu yana, yılda iki kez yeni bir JDK sürümü yayınlanıyor ve her sürüm, dilde artımlı iyileştirmeler getiriyor.

Temel bilgiler

tanımlayıcı

Bir tanımlayıcı bir unsuru adıdır kodu . Öğeler için adları seçerken izlenecek belirli standart adlandırma kuralları vardır . Java'daki tanımlayıcılar büyük/ küçük harfe duyarlıdır .

Bir tanımlayıcı şunları içerebilir:

Bir tanımlayıcı şunları yapamaz:

  • Bir rakamla başlayın.
  • Ayrılmış bir anahtar kelimeye, boş değişmeze veya boole değişmezine eşit olun.

anahtar kelimeler

Öz devam et için yeni değiştirmek
iddia etmek varsayılan git paket senkronize
boole yapmak Eğer özel Bugün nasılsın
kırmak çift uygular korumalı atmak
bayt Başka içe aktarmak halka açık atar
durum Sıralama örneği dönüş geçici
tutmak uzanır int kısa boylu denemek
karakter son arayüz statik var
sınıf nihayet uzun katı fp geçersiz
const batmadan yüzmek yerli Süper uçucu
süre

değişmezler

tamsayılar
ikili (Java SE 7'de tanıtıldı) 0b11110101 ( 0b ve ardından ikili bir sayı)
sekizli 0365 ( 0'dan sonra sekizlik bir sayı gelir)
onaltılık 0xF5 ( 0x ve ardından onaltılık bir sayı)
ondalık 245 (ondalık sayı)
Kayan nokta değerleri
batmadan yüzmek 23.5F , .5f , 1.72E3F (isteğe bağlı üs göstergeli ondalık kesir, ardından F )
0x.5FP0F , 0x.5P-6f ( 0x ardından zorunlu üs göstergesi ve F son eki olan onaltılık bir kesir )
çift 23.5D , .5 , 1.72E3D (isteğe bağlı üs göstergeli ondalık kesir, ardından isteğe bağlı D )
0x.5FP0 , 0x.5P-6D ( 0x onaltılı zorunlu üstel göstergeli fraksiyonu ve isteğe bağlı bir eki, ardından D )
Karakter değişmezleri
karakter 'a' , 'Z' , '\u0231' (tek tırnak içine alınmış karakter veya karakter çıkışı )
Boole değişmezleri
boole doğru , yanlış
boş değişmez
boş referans boş
Dize değişmezleri
Sicim "Merhaba, Dünya" (çift tırnak içine alınmış karakter dizisi ve karakter kaçışları)
Karakterler dizelerde kaçar
Unicode karakter \u3876 ( \u ardından U+ FFFF'ye kadar onaltılık unicode kod noktası gelir)
sekizli kaçış \352 (sekizli sayı 377'yi aşmaz, önünde ters eğik çizgi)
Satır besleme \n
Satırbaşı \r
Form besleme \F
ters eğik çizgi \\
Tek alıntı \'
çift ​​alıntı \"
Sekme \T
geri al \B

Tamsayı değişmezleri , sabit değerin eklenmesi veya son eki ile tür belirtilmediği intsürece varsayılan olarak türdedir, örn . Java SE 7'den beri, okunabilirliği artırmak için bir sayının rakamları arasına alt çizgi eklemek mümkündür; örneğin 145608987 sayısı 145_608_987 olarak yazılabilir . longLl367L

Değişkenler

Değişkenler , değerlerle ilişkili tanımlayıcılardır. Değişkenin türü ve adı yazılarak bildirilirler ve isteğe bağlı olarak bir değer atanarak aynı ifadede başlatılırlar.

int count;      //Declaring an uninitialized variable called 'count', of type 'int'
count = 35;     //Initializing the variable
int count = 35; //Declaring and initializing the variable at the same time

Aynı türden birden çok değişken, sınırlayıcı olarak virgül kullanılarak tek bir ifadede bildirilebilir ve başlatılabilir.

int a, b;         //Declaring multiple variables of the same type
int a = 2, b = 3; //Declaring and initializing multiple variables of the same type

Java 10'dan beri , değişkenler için türlerini kullanarak otomatik olarak türler çıkarmak mümkün hale geldi var.

// stream will have the FileOutputStream type as inferred from its initializer
var stream = new FileOutputStream("file.txt");

// An equivalent declaration with an explicit type
FileOutputStream stream = new FileOutputStream("file.txt");

Kod blokları

ayırıcılar { ve} bir kod bloğunu ve yeni bir kapsamı belirtir. Sınıf üyeleri ve bir yöntemin gövdesi, çeşitli bağlamlarda bu parantezlerin içinde nelerin yaşayabileceğine dair örneklerdir.

Yöntem gövdelerinin içinde, yeni kapsamlar oluşturmak için parantezler aşağıdaki gibi kullanılabilir:

void doSomething() {
    int a;

    {
        int b;
        a = 1;
    }

    a = 2;
    b = 3; // Illegal because the variable b is declared in an inner scope..
}

Yorumlar

Java'nın üç tür yorumu vardır: geleneksel yorumlar , satır sonu yorumları ve belge yorumları .

Blok yorumlar olarak da bilinen geleneksel yorumlar, ile başlar /*ve ile biter */, birden çok satıra yayılabilirler. Bu yorum türü C ve C++'dan türetilmiştir.

/* This is a multi-line comment.
It may occupy more than one line. */

Satır sonu yorumları //, geçerli satırın ile başlar ve sonuna kadar uzanır. Bu yorum türü, C++ ve modern C'de de mevcuttur.

// This is an end-of-line comment

Kaynak dosyalardaki dokümantasyon yorumları, dokümantasyonu oluşturmak için Javadoc aracı tarafından işlenir . Bu yorum türü /**, Javadoc aracı tarafından tanımlanan kurallarla başlaması ve bunlara uyması dışında geleneksel yorumlarla aynıdır . Teknik olarak, bu yorumlar özel bir tür geleneksel yorumdur ve dil belirtiminde özel olarak tanımlanmamıştır.

/**
 * This is a documentation comment.
 * 
 * @author John Doe
 */

Evrensel tipler

Java.lang paketindeki sınıflar, açıkça içe aktarılan türler aynı ada sahip olmadığı sürece, her programa örtük olarak içe aktarılır. Önemli olanlar şunları içerir:

java.lang.Nesne
Java'nın en iyi türü . Bir üst sınıf bildirmeyen tüm sınıfların üst sınıfı. Tüm değerler bu türe dönüştürülebilir, ancak ilkel değerler için bu otomatik kutulamayı içerir .
java.lang.Dize
Java'nın temel dize türü. değişmez . Bazı yöntemler, her UTF-16 kod birimini bir "karakter" olarak ele alır, ancak int[]etkin bir şekilde UTF-32'ye dönüştürme yöntemleri de mevcuttur.
java.lang.Atılabilir
edilebilir şeyin süpertip atılmış ya yakalandı Java'nın ile throwve catchtablolar.

Program yapısı

Java uygulamaları sınıf koleksiyonlarından oluşur. Sınıflar paketlerde bulunur, ancak diğer sınıfların içine de yerleştirilebilir.

main yöntem

Her Java uygulamasının bir giriş noktası olmalıdır. Bu, hem grafik arayüz uygulamaları hem de konsol uygulamaları için geçerlidir. Giriş noktası mainyöntemdir. Bir yöntemle birden fazla sınıf olabilir main, ancak ana sınıf her zaman harici olarak tanımlanır (örneğin, bir bildirim dosyasında ). Yöntem static, bir dizi dize olarak komut satırı bağımsız değişkenleri olmalıdır ve iletilir. C++ veya C#'dan farklı olarak , hiçbir zaman bir değer döndürmez ve döndürmesi gerekir void.

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

Paketler

Paketler bir sınıf adının bir parçasıdır ve adlandırılmış varlıkları diğerlerinden ayırmak ve/veya gruplamak için kullanılırlar. Paketlerin bir diğer amacı da erişim değiştiricileri ile birlikte kod erişimini yönetmektir. Örneğin , pakette bulunan java.io.InputStreamsınıf için tam nitelikli bir sınıf adıdır . InputStreamjava.io

Dosyanın başında aşağıdaki packagebildirimle bir paket bildirilir:

package myapplication.mylibrary;

public class MyClass {
}

publicDeğiştiricili sınıflar , aynı isim ve java uzantılı dosyalara yerleştirilmeli ve paket adına karşılık gelen iç içe klasörlere yerleştirilmelidir. Yukarıdaki sınıf myapplication.mylibrary.MyClassaşağıdaki yola sahip olacaktır: myapplication/mylibrary/MyClass.java.

İthalat beyanı

Tip ithalat beyanı

Bir tür içe aktarma bildirimi, adlandırılmış bir türe paketi içeren tam ad yerine basit bir adla başvurulmasına izin verir. İthalat beyanları, tek tip ithalat beyanları veya talep üzerine ithal beyanları olabilir . İthalat beyanları, paket beyanından sonra bir kod dosyasının en üstüne yerleştirilmelidir.

package myPackage;

import java.util.Random; // Single type declaration

public class ImportsTest {
    public static void main(String[] args) {
        /* The following line is equivalent to
         * java.util.Random random = new java.util.Random();
         * It would've been incorrect without the import.
         */
        Random random = new Random();
    }
}

İsteğe bağlı içe aktarma bildirimleri kodda belirtilmiştir. Bir "tür içe aktarma", paketin tüm türlerini içe aktarır. Bir "statik içe aktarma", paketin üyelerini içe aktarır.

import java.util.*;  /*This form of importing classes makes all classes
    in package java.util available by name, could be used instead of the
    import declaration in the previous example. */
import java.*; /*This statement is legal, but does nothing, since there
    are no classes directly in package java. All of them are in packages
    within package java. This does not import all available classes.*/

Statik ithalat beyanı

Bu tür bir bildirim J2SE 5.0'dan beri mevcuttur . Statik içe aktarma bildirimleri, başka bir sınıf, arabirim, ek açıklama veya numaralandırmada tanımlanan statik üyelere erişime izin verir; sınıf adını belirtmeden:

import static java.lang.System.out; //'out' is a static field in java.lang.System

public class HelloWorld {
    public static void main(String[] args) {
        /* The following line is equivalent to:
   System.out.println("Hi World!");

           and would have been incorrect without the import declaration. */
        out.println("Hello World!");
    }
}

İsteğe bağlı içe aktarma bildirimleri, türün tüm alanlarının içe aktarılmasına izin verir:

import static java.lang.System.*;
    /* This form of declaration makes all
       fields in the java.lang.System class available by name, and may be used instead
       of the import declaration in the previous example. */

Enum sabitleri, statik içe aktarma ile de kullanılabilir. Örneğin, bu numaralandırma adı verilen pakette screen:

public enum ColorName {
    RED, BLUE, GREEN
};

Enum sabitlerini almak için başka bir sınıfta statik içe aktarma bildirimlerini kullanmak mümkündür:

import screen.ColorName;
import static screen.ColorName.*;

public class Dots {
    /* The following line is equivalent to 'ColorName foo = ColorName.RED',
       and it would have been incorrect without the static import. */
    ColorName foo = RED;

    void shift() {
        /* The following line is equivalent to:

           if (foo == ColorName.RED) foo = ColorName.BLUE; */
        if (foo == RED) foo = BLUE;
    }
}

operatörler

Java'daki operatörler, C++'dakilere benzer . Ancak Java'da çöp toplama mekanizmaları deletenedeniyle operatör yoktur ve Java onları desteklemediği için işaretçiler üzerinde herhangi bir işlem yoktur . Diğer bir fark, Java'nın işaretsiz bir sağa kaydırma operatörüne ( ) sahip olması, C'nin sağa kaydırma operatörünün imzasının ise türe bağlı olmasıdır. Java'daki operatörler aşırı yüklenemez . >>>

Öncelik Şebeke Açıklama çağrışım
1 () Yöntem çağırma Soldan sağa
[] dizi erişimi
. Sınıf üyesi seçimi
2 ++ -- Postfix artırma ve azaltma
3 ++ -- Önek artırma ve azaltma Sağdan sola
+ - Tekli artı ve eksi
! ~ Mantıksal DEĞİL ve bit düzeyinde DEĞİL
(type) val Tip döküm
new Sınıf örneği veya dizi oluşturma
4 * / % Çarpma, bölme ve modül (kalan) Soldan sağa
5 + - Toplama ve çıkarma
+ dize bitiştirme
6 << >> >>> Bit düzeyinde sola kaydırma, işaretli sağa kaydırma ve işaretsiz sağa kaydırma
7 < <= İlişkisel "küçüktür" ve "küçüktür veya eşittir"
> >= İlişkisel “büyüktür” ve “büyüktür veya eşittir”
instanceof Tür karşılaştırması
8 == != İlişkisel “eşittir” ve “eşit değildir”
9 & Bit düzeyinde ve mantıksal VE
10 ^ Bit düzeyinde ve mantıksal XOR (özel veya)
11 | Bit düzeyinde ve mantıksal VEYA (dahil veya)
12 && Mantıksal koşullu-VE
13 || Mantıksal koşullu-VEYA
14 c ? t : f Üçlü koşullu (bkz. ?: ) Sağdan sola
15 = Basit atama
+= -= Toplama ve farka göre atama
*= /= %= Ürün, bölüm ve kalana göre atama
<<= >>= >>>= Bit düzeyinde sola kaydırma, işaretli sağa kaydırma ve işaretsiz sağa kaydırma ile atama
&= ^= |= Bit düzeyinde AND, XOR ve OR ile atama

Kontrol Yapıları

koşullu ifadeler

if Beyan

Java'daki if ifadeleri C'dekilere benzerse ve aynı sözdizimini kullanır:

if (i == 3) doSomething();

ififadesi isteğe bağlı elseblok içerebilir , bu durumda bir if-then-else ifadesi olur:

if (i == 2) {
    doSomething();
} else {
    doSomethingElse();
}

C gibi, else-if yapısı herhangi bir özel anahtar kelime içermiyorsa, ayrı if-then-else ifadelerinin bir dizisi olarak oluşturulur:

if (i == 3) {
    doSomething();
} else if (i == 2) {
    doSomethingElse();
} else {
    doSomethingDifferent();
}

Ayrıca, ?: operatörünün basit if ifadesi yerine kullanılabileceğini unutmayın , örneğin

int a = 1;
int b = 2;
int minVal = (a < b) ? a : b;

switch Beyan

Java'daki switch deyimleribyte , short, char, ve int(not: not long) ilkel veri türlerini veya bunlara karşılık gelen sarmalayıcı türlerini kullanabilir. J2SE 5.0 ile başlayarak, enum türlerini kullanmak mümkündür . Java SE 7 ile başlayarak, Dizeleri kullanmak mümkündür. Diğer referans türleriswitch deyimlerde kullanılamaz .

Olası değerler caseetiketler kullanılarak listelenir . Java'daki bu etiketler yalnızca sabitleri içerebilir (enum sabitleri ve dize sabitleri dahil). Yürütme, parantez içindeki ifadeye karşılık gelen etiketten sonra başlayacaktır. defaultDurum etiketlerinden hiçbiri ifadeye karşılık gelmezse, onu takip eden kodun yürütüleceğini bildirmek için isteğe bağlı bir etiket mevcut olabilir.

Her etiketin kodu breakanahtar kelime ile biter . Yürütmenin bir sonraki etikete geçmesine neden olacak şekilde atlamak mümkündür, ancak derleme sırasında genellikle bir uyarı rapor edilir.

switch (ch) {
    case 'A':
        doSomething(); // Triggered if ch == 'A'
        break;
    case 'B':
    case 'C':
        doSomethingElse(); // Triggered if ch == 'B' or ch == 'C'
        break;
    default:
        doSomethingDifferent(); // Triggered in any other case
        break;
}
switch ifade

Java 14'ten bu yana, yeni ok sözdizimini kullanan anahtar ifadelerini kullanmak mümkün hale geldi:

var result = switch (ch) {
    case 'A' -> Result.GREAT;
    case 'B', 'C' -> Result.FINE;
    default -> throw new ThisIsNoGoodException();
};

Alternatif olarak, aynı şeyi yieldifadeyle ifade etme olasılığı vardır , ancak yanlışlıkla düşme sorununu ortadan kaldırdığı için ok sözdizimini tercih etmeniz önerilir.

var result = switch (ch) {
    case 'A':
        yield Result.GREAT;
    case 'B':
    case 'C':
        yield Result.FINE;
    default:
        throw new ThisIsNoGoodException();
};

yineleme ifadeleri

Yineleme ifadeleri, belirli bir koşul doğru olarak değerlendirildiğinde tekrar tekrar yürütülen ifadelerdir. J2SE 5.0'dan beri Java, bu tür ifadelerin dört biçimine sahiptir.

while döngü

Olarak whiledöngü, deney, her yineleme önce yapılır.

while (i < 10) {
    doSomething();
}

do ... while döngü

Olarak do ... whiledöngü, deney, her yineleme sonrası yapılır. Sonuç olarak, kod her zaman en az bir kez yürütülür.

// doSomething() is called at least once
do {
    doSomething();
} while (i < 10);

for döngü

forJava'daki döngüler bir başlatıcı, bir koşul ve bir sayaç ifadesi içerir. Sınırlayıcı olarak virgül kullanarak aynı türden birkaç ifadeyi dahil etmek mümkündür (koşul dışında). Ancak, C'den farklı olarak, virgül yalnızca bir sınırlayıcıdır ve bir işleç değildir.

for (int i = 0; i < 10; i++) {
    doSomething();
}
 
// A more complex loop using two variables
for (int i = 0, j = 9; i < 10; i++, j -= 3) {
    doSomething();
}

C gibi, üç ifade de isteğe bağlıdır. Aşağıdaki döngü sonsuzdur:

for (;;) {
    doSomething();
}

Gelişmiş fordöngü

Gelişmiş fordöngüler J2SE 5.0'dan beri mevcuttur . Bu döngü türü, verilen koleksiyondaki her öğeyi döndürmek için diziler ve koleksiyonlar üzerinde yerleşik yineleyiciler kullanır. Her öğe, kod bloğu bağlamında döndürülür ve erişilebilir. Blok yürütüldüğünde, kalan öğe kalmayana kadar sonraki öğe döndürülür. C#' tan farklı olarak , bu tür döngü özel bir anahtar sözcük içermez, bunun yerine farklı bir gösterim stili kullanır.

for (int i : intArray) {
    doSomething(i);
}

ifadeleri atla

Etiketler

Etiketlere breakve continueifadeleri tarafından kullanılan kodda noktalar verilir . Java gotoanahtar sözcüğünün koddaki belirli noktalara atlamak için kullanılamayacağını unutmayın .

start:
someMethod();

break Beyan

breakDeyimi en yakın döngü veya patlak switchaçıklamada. Yürütme, varsa sonlandırılan ifadeden sonra beyannamede devam eder.

for (int i = 0; i < 10; i++) {
    while (true) {
        break;
    }
    // Will break to this point
}

Etiketleri kullanarak dış döngüden çıkmak mümkündür:

outer:
for (int i = 0; i < 10; i++) {
    while (true) {
        break outer;
    }
}
// Will break to this point

continue Beyan

continueDeyim geçerli kontrol deyimi anki adımını durdurursa ve bir sonraki iterasyon başlar. Aşağıdaki whilekoddaki aşağıdaki döngü, karakterleri çağırarak okur, karakterler getChar()boşluksa döngü gövdesindeki ifadeleri atlar:

int ch;
while (ch == getChar()) {
    if (ch == ' ') {
        continue; // Skips the rest of the while-loop
    }

    // Rest of the while-loop, will not be reached if ch == ' '
    doSomething();
}

Etiketler, continueifadelerde ve breakifadelerde belirtilebilir :

outer:
for (String str : stringsArr) {
    char[] strChars = str.toCharArray();
    for (char ch : strChars) {
        if (ch == ' ') {
            /* Continues the outer cycle and the next
            string is retrieved from stringsArr */
            continue outer;
        }
        doSomething(ch);
    }
}

return Beyan

returnBildirimi yöntemi icra son vermek ve bir değer iade etmek için kullanılır. returnAnahtar kelimeden sonra metot tarafından döndürülen bir değer yazılır . Yöntem, dışında bir şey döndürürse void, returnbir değer döndürmek için ifadeyi kullanmalıdır .

void doSomething(boolean streamClosed) {
    // If streamClosed is true, execution is stopped
    if (streamClosed) {
        return;
    }
    readFromStream();
}

int calculateSum(int a, int b) {
    int result = a + b;
    return result;
}

returnBir durum dışında deyim yürütmeyi hemen sona erdirir: deyimle bir tryblok içinde karşılaşılırsa ve bir ile tamamlanırsa finally, kontrol finallybloğa iletilir .

void doSomething(boolean streamClosed) {
    try {
        if (streamClosed) {
            return;
        }
        readFromStream();
    } finally {
        /* Will be called last even if 
        readFromStream() was not called */
        freeResources();
    }
}

İstisna işleme ifadeleri

try-catch-finally ifadeler

İstisnalar try... catchblokları içinde yönetilir .

try {
    // Statements that may throw exceptions
    methodThrowingExceptions();
} catch (Exception ex) {
    // Exception caught and handled here
    reportException(ex);
} finally {
    // Statements always executed after the try/catch blocks
    freeResources();
}

tryBlok içindeki ifadeler yürütülür ve bunlardan herhangi biri bir istisna atarsa, bloğun yürütülmesi durdurulur ve istisna catchblok tarafından işlenir . Birden çok catchblok olabilir; bu durumda, türü, atılan istisnanın türüyle eşleşen bir istisna değişkenine sahip ilk blok yürütülür.

Java SE 7, tek yakalama yan tümcelerinin yanı sıra çoklu yakalama yan tümcelerini de tanıttı. Bu tür yakalama yan tümceleri, Java'nın, birbirlerinin alt sınıfları olmamaları koşuluyla, tek bir blokta farklı türdeki istisnaları işlemesine olanak tanır.

try {
    methodThrowingExceptions();
} catch (IOException | IllegalArgumentException ex) {
    //Both IOException and IllegalArgumentException will be caught and handled here
    reportException(ex);
}

Hiçbir catchblok, atılan istisna türüyle eşleşmiyorsa, try... catchifadesini içeren dış bloğun (veya yöntemin) yürütülmesine devam edilmez ve istisna geçirilir ve içeren bloğun (veya yöntemin) dışına çıkar. İstisna, o anda etkin olan yöntemlerden birinde eşleşen bir blok bulunana kadar çağrı yığını boyunca yukarı doğru yayılır catch. İstisna, maineşleşen bir catchblok bulunmadan en üstteki yönteme kadar yayılırsa, standart çıktı akışına istisnanın metinsel bir açıklaması yazılır.

Bir istisna atılmış olsun ya da olmasın ve bir ifadeye ulaşılsa bile , finallyblok içindeki ifadeler her zaman tryve catchbloklarından sonra yürütülür return. Bu tür bloklar, her zaman yürütüleceği garanti edilen temizleme kodu sağlamak için kullanışlıdır.

catchVe finallyblok isteğe bağlıdır, ancak en az bir ya da takip eden mevcut olmalıdır tryblok.

try-kaynaklı ifadeler

try-with-kaynaklar ifadeleri özel bir türüdür try-catch-finallybir uygulama olarak tanıtılan ifadeleri atmayın deseni bir de Java SE 7'de try-with-kaynaklar deyimi tryotomatik olarak serbest bırakılır anahtar kelimenin bir veya daha fazla kaynak başlatma takip eder tryblok yürütme bitti. Kaynaklar uygulamak zorundadır java.lang.AutoCloseable. try-with-resources deyimlerinin, normal deyimlerden farklı olarak a catchveya finallybloğuna sahip olması gerekmez try-catch-finally.

try (FileOutputStream fos = new FileOutputStream("filename");
    XMLEncoder xEnc = new XMLEncoder(fos)) {
    xEnc.writeObject(object);
} catch (IOException ex) {
    Logger.getLogger(Serializer.class.getName()).log(Level.SEVERE, null, ex);
}

Java 9'dan beri önceden tanımlanmış değişkenleri kullanmak mümkündür:

FileOutputStream fos = new FileOutputStream("filename");
XMLEncoder xEnc = new XMLEncoder(fos);
try (fos; xEnc) {
    xEnc.writeObject(object);
} catch (IOException ex) {
    Logger.getLogger(Serializer.class.getName()).log(Level.SEVERE, null, ex);
}

throw Beyan

throwBildirimi, bir özel durum ve blok ya da yöntemin yürütülmesine sona erdirmek için kullanılır. Atılan istisna örneği, throwifadeden sonra yazılır .

void methodThrowingExceptions(Object obj) {
    if (obj == null) {
        // Throws exception of NullPointerException type
        throw new NullPointerException();
    }
    // Will not be called, if object is null
    doSomethingWithObject(obj);
}

İş parçacığı eşzamanlılık kontrolü

Java, çok iş parçacıklı programlama için yerleşik araçlara sahiptir . İş parçacığı senkronizasyonu amacıyla , synchronizedifade Java diline dahil edilmiştir.

Bir kod bloğunu senkronize hale getirmek için synchronized, parantez içindeki kilit nesnesi tarafından takip edilen anahtar kelimeden önce gelir . Yürütme iş parçacığı senkronize bloğa ulaştığında, karşılıklı bir dışlama kilidi alır, bloğu yürütür ve ardından kilidi serbest bırakır. Kilit açılana kadar hiçbir iş parçacığı bu bloğa giremez. Null olmayan herhangi bir referans tipi kilit olarak kullanılabilir.

/* Acquires lock on someObject. It must be of
a reference type and must be non-null */
synchronized (someObject) {
    // Synchronized statements
}

assert Beyan

assertifadeler J2SE 1.4'ten beri mevcuttur . Bu tür ifadeler, belirli sınıflar veya paketler için yürütme sırasında açılıp kapatılabilen kaynak kodda iddialarda bulunmak için kullanılır . Bir iddia beyan etmek için assertanahtar kelime ve ardından bir koşullu ifade kullanılır. İfadenin falsene zaman yürütüldüğünü değerlendirirse, bir istisna atılır. Bu ifade, iki nokta üst üste işaretinin ardından istisnanın ayrıntı mesajı olarak işlev görecek başka bir ifade içerebilir.

// If n equals 0, AssertionError is thrown
assert n != 0;
/* If n equals 0, AssertionError will be thrown
with the message after the colon */
assert n != 0 : "n was equal to zero";

İlkel türler

Java'daki ilkel türler arasında tamsayı türleri, kayan nokta sayıları, UTF-16 kod birimleri ve bir boole türü bulunur. charUTF-16 kod birimlerini temsil etmek için kullanılan tür dışında Java'da imzasız tür yoktur . İmzasız türlerin eksikliği, >>>C++'da mevcut olmayan imzasız sağa kaydırma işlemi ( ) getirilerek dengelenir . Bununla birlikte, bunun neden olduğu C ve C++ ile uyumsuzluk konusunda eleştiriler tesviye edilmiştir.

İlkel Türler
Tür Adı sarıcı sınıfı Değer Menzil Boy Varsayılan değer
byte java.lang.Byte tam sayı -128 ile +127 arası 8 bit (1 bayt) 0
short java.lang.Short tam sayı -32.768 ile +32.767 arası 16 bit (2 bayt) 0
int java.lang.Integer tam sayı -2,147,483,648 ile +2,147,483,647 arası 32 bit (4 bayt) 0
long java.lang.Long tam sayı −9,223,372,036,854,775,808 ile
+9,223,372,036,854,775,807 arası
64 bit (8 bayt) 0
float java.lang.Float kayan nokta sayısı ±1.401298E−45 ila ±3.402823E+38 32 bit (4 bayt) 0.0f
double java.lang.Double kayan nokta sayısı ±4.94065645841246E−324 ila
±1.79769313486232E+308
64 bit (8 bayt) 0.0
boolean java.lang.Boolean Boole true veya false 1 bit (1 bit) false
char java.lang.Character UTF-16 kod birimi ( BMP karakteri
veya bir yedek çiftin parçası)
'\u0000' vasıtasıyla '\uFFFF' 16 bit (2 bayt) '\u0000'

charmutlaka tek bir karaktere karşılık gelmez. Bir vekil çiftin bir parçasını temsil edebilir , bu durumda Unicode kod noktası iki chardeğer dizisi ile temsil edilir .

Boks ve kutu açma

Bu dil özelliği J2SE 5.0'da tanıtıldı . Boks , ilkel bir türün değerini, bu belirli ilkel tür için bir sarmalayıcı görevi gören, karşılık gelen bir referans türünün değerine dönüştürme işlemidir. Kutudan çıkarma , bir referans türünün (önceden kutulanmış) bir değerini karşılık gelen bir ilkel türün değerine dönüştürmenin tersi işlemidir. Her iki işlem de açık bir dönüştürme gerektirmez.

Örnek:

int foo = 42; // Primitive type
Integer bar = foo; /* foo is boxed to bar, bar is of Integer type,
                      which serves as a wrapper for int */
int foo2 = bar; // Unboxed back to primitive type

Referans türleri

Başvuru türleri, sınıf türlerini, arabirim türlerini ve dizi türlerini içerir. Yapıcı çağrıldığında, öbek üzerinde bir nesne oluşturulur ve değişkene bir başvuru atanır. Bir nesnenin değişkeni kapsam dışına çıktığında referans bozulur ve referans kalmadığında nesne çöp olarak işaretlenir. Çöp toplayıcı daha sonra onu toplar ve bir süre sonra yok eder.

Bir referans değişkeni, nullherhangi bir nesneye referans vermediği zamandır.

diziler

Java'daki diziler, tıpkı sınıf örnekleri gibi çalışma zamanında oluşturulur. Dizi uzunluğu oluşturulurken tanımlanır ve değiştirilemez.

int[] numbers = new int[5];
numbers[0] = 2;
numbers[1] = 5;
int x = numbers[0];

Başlatıcılar

// Long syntax
int[] numbers = new int[] {20, 1, 42, 15, 34};
// Short syntax
int[] numbers2 = {20, 1, 42, 15, 34};

Çok boyutlu diziler

Java'da çok boyutlu diziler, dizi dizileri olarak temsil edilir. Teknik olarak, diğer dizilere yapılan başvuru dizileriyle temsil edilirler.

int[][] numbers = new int[3][3];
numbers[1][2] = 2;

int[][] numbers2 = {{2, 3, 2}, {1, 2, 6}, {2, 4, 5}};

Çok boyutlu dizilerin doğası gereği, alt dizilerin uzunlukları değişebilir, bu nedenle çok boyutlu diziler C'den farklı olarak dikdörtgen olmaya bağlı değildir:

int[][] numbers = new int[2][]; //Initialization of the first dimension only

numbers[0] = new int[3];
numbers[1] = new int[2];

sınıflar

Sınıflar , Java gibi nesne yönelimli bir dilin temelleridir. Verileri depolayan ve işleyen üyeler içerirler. Sınıflar üst düzey ve iç içe . İç içe sınıflar, çevreleyen sınıfın özel üyelerine erişebilen başka bir sınıfın içine yerleştirilmiş sınıflardır. İç içe sınıflar, üye sınıfları ( basit iç içe yerleştirme için statik değiştiriciyle veya iç sınıflar için onsuz tanımlanabilir ), yerel sınıfları ve anonim sınıfları içerir .

beyanname

Üst düzey sınıf
class Foo {
    // Class members
}
iç sınıf
class Foo { // Top-level class
    class Bar { // Inner class
    }
}
iç içe sınıf
class Foo { // Top-level class
    static class Bar { // Nested class
    }
}
yerel sınıf
class Foo {
    void bar() {
        class Foobar {// Local class within a method
        }
    }
}
anonim sınıf
class Foo {
    void bar() {
        new Object() {// Creation of a new anonymous class extending Object
        };
    }
}

örnekleme

Bir sınıfın statik olmayan üyeleri, o sınıftan oluşturulan nesnelerle ilgili örnek değişkenlerin ve yöntemlerin türlerini tanımlar . Bu nesneleri oluşturmak için, newoperatör kullanılarak ve sınıf yapıcısı çağrılarak sınıfın somutlaştırılması gerekir .

Foo foo = new Foo();

Üyelere erişim

Hem örneklerin hem de statik sınıfların üyelerine .(nokta) operatörüyle erişilir .

Bir örnek üyeye erişim
Örnek üyelerine bir değişkenin adı aracılığıyla erişilebilir.

String foo = "Hello";
String bar = foo.toUpperCase();

Statik bir sınıf üyesine erişim
Statik üyelere, sınıfın adı veya başka bir tür kullanılarak erişilir. Bu, bir sınıf örneğinin oluşturulmasını gerektirmez. Statik üyeler staticdeğiştirici kullanılarak bildirilir .

public class Foo {
    public static void doSomething() {
    }
}

// Calling the static method
Foo.doSomething();

değiştiriciler

Değiştiriciler, türlerin ve tür üyelerinin bildirimlerini değiştirmek için kullanılan anahtar sözcüklerdir. En önemlisi, erişim değiştiricileri içeren bir alt grup vardır.

  • abstract - Bir sınıfın yalnızca temel sınıf olarak hizmet ettiğini ve somutlaştırılamayacağını belirtir.
  • static - Yalnızca üye sınıflar için kullanılır, üye sınıfın, içeren sınıfın belirli bir örneğine ait olmadığını belirtir.
  • final- Olarak işaretlenen sınıflar finalgenişletilemez ve alt sınıfları olamaz.
  • strictfp- Tüm kayan nokta işlemlerinin IEEE 754'e uygun olarak gerçekleştirilmesi gerektiğini belirtir ve ara sonuçları depolamak için gelişmiş kesinlik kullanılmasını yasaklar.
Erişim değiştiricileri

Erişim değiştiricileri veya miras değiştiriciler , sınıflar, yöntemler ve diğer üyelerin erişilebilirliğini ayarlayın. publicHer yerden ulaşılabilir olarak işaretlenen üyeler . Bir sınıf veya üyesi herhangi bir değiştiriciye sahip değilse, varsayılan erişim varsayılır.

public class Foo {
    int go() {
        return 0;
    }

    private class Bar {
    }
}

Aşağıdaki tablo, erişilen sınıf konumuna ve erişilen sınıf veya sınıf üyesi için değiştiriciye bağlı olarak bir sınıf içindeki kodun sınıfa mı yoksa yönteme mi erişimi olduğunu gösterir:

değiştirici Aynı sınıf veya iç içe sınıf Aynı paket içindeki diğer sınıf Başka bir paket içinde Genişletilmiş Sınıf Başka bir paketin içinde genişletilmemiş
private Evet numara numara numara
varsayılan (paket özel) Evet Evet numara numara
protected Evet Evet Evet numara
public Evet Evet Evet Evet
Image
Bu görüntü, sınıflar ve paketler içindeki sınıf üyesi kapsamını açıklar.

Yapıcılar ve başlatıcılar

Bir yapıcı bir amacı başlatıldığında olarak adlandırılan özel bir yöntemdir. Amacı, nesnenin üyelerini başlatmaktır. Yapıcılar ve sıradan yöntemler arasındaki temel fark, yapıcıların yalnızca sınıfın bir örneği oluşturulduğunda çağrılması ve hiçbir zaman hiçbir şey döndürmemesidir. Yapıcılar ortak yöntemler olarak bildirilir, ancak sınıftan sonra adlandırılırlar ve herhangi bir dönüş türü belirtilmez:

class Foo {
    String str;

    Foo() { // Constructor with no arguments

        // Initialization
    }

    Foo(String str) { // Constructor with one argument
        this.str = str;
    }
}

Başlatıcılar, bir sınıf veya bir sınıf örneği oluşturulduğunda yürütülen kod bloklarıdır. İki tür başlatıcı vardır, statik başlatıcılar ve örnek başlatıcılar .

Statik başlatıcılar, sınıf oluşturulduğunda statik alanları başlatır. staticAnahtar kelime kullanılarak bildirilirler :

class Foo {
    static {
        // Initialization
    }
}

Bir sınıf yalnızca bir kez oluşturulur. Bu nedenle, statik başlatıcılar bir kereden fazla çağrılmaz. Aksine, sınıfın bir örneği her oluşturulduğunda, bir kurucu çağrısından önce örnek başlatıcılar otomatik olarak çağrılır. Yapıcılardan farklı olarak, örnek başlatıcılar herhangi bir argüman alamazlar ve genellikle kontrol edilen istisnaları atamazlar (birkaç özel durum dışında). Örnek başlatıcılar, herhangi bir anahtar kelime olmadan bir blokta bildirilir:

class Foo {
    {
        // Initialization
    }
}

Java'nın çöp toplama mekanizması olduğu için yıkıcılar yoktur . Ancak, her nesnenin finalize()çöp toplamadan önce çağrılan ve sonlandırmayı uygulamak için geçersiz kılınabilen bir yöntemi vardır .

yöntemler

Java'daki tüm ifadeler yöntemler içinde bulunmalıdır. Yöntemler, sınıflara ait olmaları dışında işlevlere benzer. Bir yöntemin bir dönüş değeri, bir adı ve genellikle bazı argümanlarla çağrıldığında başlatılan bazı parametreleri vardır. C++'a benzer şekilde, hiçbir şey döndürmeyen yöntemlerin dönüş türü void. C++'dan farklı olarak, Java'daki yöntemlerin varsayılan argüman değerlerine sahip olmasına izin verilmez ve bunun yerine yöntemler genellikle aşırı yüklenir.

class Foo {
    int bar(int a, int b) {
        return (a*2) + b;
    }

    /* Overloaded method with the same name but different set of arguments */
    int bar(int a) {
        return a*2;
    }
}

Bir .nesne üzerinde notasyon kullanılarak veya statik bir yöntem durumunda, ayrıca bir sınıf adına da bir yöntem çağrılır .

Foo foo = new Foo();
int result = foo.bar(7, 2); // Non-static method is called on foo

int finalResult = Math.abs(result); // Static method call

throwsAnahtar kelime bir yöntem bir istisna atar belirtir. Tüm işaretli istisnalar, virgülle ayrılmış bir listede listelenmelidir.

void openStream() throws IOException, myException { // Indicates that IOException may be thrown
}
değiştiriciler
  • abstract- Soyut yöntemler yalnızca soyut sınıflarda bulunabilir , bu tür yöntemlerin gövdesi yoktur ve kendisi soyut olmadığı sürece bir alt sınıfta geçersiz kılınmalıdır.
  • static- Bir sınıf örneği oluşturmadan yöntemi statik ve erişilebilir hale getirir. Ancak statik yöntemler, aynı sınıftaki statik olmayan üyelere erişemez.
  • final - Yöntemin bir alt sınıfta geçersiz kılınamayacağını bildirir.
  • native- Bu yöntemin platforma bağlı kodda JNI aracılığıyla uygulandığını belirtir . Gerçek uygulama Java kodunun dışında gerçekleşir ve bu tür yöntemlerin gövdesi yoktur.
  • strictfp- Kayan nokta işlemlerini gerçekleştirirken IEEE 754'e katı şekilde uygun olduğunu beyan eder .
  • synchronized- Bu yöntemi çalıştıran bir iş parçacığının monitör alması gerektiğini bildirir. İçin synchronizedyöntemlerle monitör sınıfı örneğidir veya java.lang.Classeğer yöntem statiktir.
  • Erişim değiştiricileri - Sınıflarla kullanılanlarla aynıdır.
Vararglar

Bu dil özelliği J2SE 5.0'da tanıtıldı . Yöntemin son argümanı bir değişken arity parametresi olarak bildirilebilir, bu durumda yöntem bir değişken arity yöntemi (sabit arity yöntemlerinin aksine) veya basitçe varargs yöntemi olur. Bu, beyan edilen türden değişken sayıda değeri parametre olarak - parametresiz olarak - yönteme geçirmeye izin verir. Bu değerler, yöntemin içinde bir dizi olarak bulunacaktır.

void printReport(String header, int... numbers) { //numbers represents varargs
    System.out.println(header);
    for (int num : numbers) {
        System.out.println(num);
    }
}

// Calling varargs method
printReport("Report data", 74, 83, 25, 96);

Alanlar

Alanlar veya sınıf değişkenleri , verileri depolamak için sınıf gövdesi içinde bildirilebilir.

class Foo {
    double bar;
}

Alanlar, bildirildiğinde doğrudan başlatılabilir.

class Foo {
    double bar = 2.3;
}
değiştiriciler
  • static - Alanı statik üye yapar.
  • final - Alanın bir kurucuda veya başlatma bloğunun içinde veya bildirimi sırasında (hangisi daha önceyse) yalnızca bir kez başlatılmasına izin verir.
  • transient- Serileştirme sırasında bu alanın saklanmayacağını belirtir .
  • volatile- Bir alan bildirilmişse volatile, tüm iş parçacıklarının değişken için tutarlı bir değer görmesi sağlanır.

Miras

Java Sınıfları tek edebilir devralan gelen bir sınıfa. Bir sınıf, olarak işaretlenmemiş herhangi bir sınıftan türetilebilir final. Kalıtım, extendsanahtar kelime kullanılarak bildirilir . Bir sınıf, thisanahtar kelimeyi kullanarak kendisine ve anahtar kelimeyi kullanarak doğrudan üst sınıfına başvurabilir super.

class Foo {

}

class Foobar extends Foo {

}

Bir sınıf kendi üst sınıfını belirtmezse, dolaylı olarak java.lang.Objectsınıftan miras alır . Böylece Java'daki tüm sınıflar, Objectsınıfın alt sınıflarıdır.

Üst sınıfın parametreleri olmayan bir yapıcısı yoksa, alt sınıfın, üst sınıfın hangi yapıcısının kullanılacağını yapıcılarında belirtmesi gerekir. Örneğin:

class Foo {
    public Foo(int n) {
        // Do something with n
    }
}

class Foobar extends Foo {
    private int number;
    // Superclass does not have constructor without parameters
    // so we have to specify what constructor of our superclass to use and how

    public Foobar(int number) {
        super(number);
        this.number = number;
    }
}
geçersiz kılma yöntemleri

C++'dan farklı olarak final, Java'daki tüm yöntemler sanaldır ve miras alınan sınıflar tarafından geçersiz kılınabilir.

class Operation {
    public int doSomething() {
        return 0;
    }
}

class NewOperation extends Operation {
    @Override
    public int doSomething() {
        return 1;
    }
}
Soyut sınıflar

Bir Özet Sınıf eksik veya eksik dikkate alınması gereken bir sınıftır. Normal sınıflar, yalnızca soyut sınıflarsa, bildirilmiş ancak henüz uygulanmamış yöntemler olan soyut yöntemlere sahip olabilir. Aşağıdakilerden herhangi biri doğruysa, C sınıfı soyut yöntemlere sahiptir:

  • C açıkça soyut bir yöntemin bildirimini içerir.
  • C'nin üst sınıflarından herhangi birinin soyut bir yöntemi vardır ve C, onu uygulayan bir yöntemi ne bildirir ne de devralır.
  • C'nin doğrudan bir süper arayüzü, bir yöntemi bildirir veya devralır (bu nedenle zorunlu olarak soyuttur) ve C, onu uygulayan bir yöntemi ne bildirir ne de devralır.
  • Soyut bir sınıfın kendisi soyut olmayan bir alt sınıfı somutlaştırılabilir, bu da soyut sınıf için bir kurucunun yürütülmesine ve dolayısıyla o sınıfın örnek değişkenleri için alan başlatıcılarının yürütülmesine neden olabilir.
package org.dwwwp.test;

/**
 * @author jcrypto
 */
public class AbstractClass {
    private static final String hello;

    static {
        System.out.println(AbstractClass.class.getName() + ": static block runtime");
        hello = "hello from " + AbstractClass.class.getName();
    }

    {
        System.out.println(AbstractClass.class.getName() + ": instance block runtime");
    }

    public AbstractClass() {
        System.out.println(AbstractClass.class.getName() + ": constructor runtime");
    }

    public static void hello() {
        System.out.println(hello);
    }
}
package org.dwwwp.test;

/**
 * @author jcrypto
 */
public class CustomClass extends AbstractClass {

    static {
        System.out.println(CustomClass.class.getName() + ": static block runtime");
    }

    {
        System.out.println(CustomClass.class.getName() + ": instance block runtime");
    }

    public CustomClass() {
        System.out.println(CustomClass.class.getName() + ": constructor runtime");
    }

    public static void main(String[] args) {
        CustomClass nc = new CustomClass();
        hello();
        //AbstractClass.hello();//also valid
    }
}

Çıktı:

org.dwwwp.test.AbstractClass: static block runtime
org.dwwwp.test.CustomClass: static block runtime
org.dwwwp.test.AbstractClass: instance block runtime
org.dwwwp.test.AbstractClass: constructor runtime
org.dwwwp.test.CustomClass: instance block runtime
org.dwwwp.test.CustomClass: constructor runtime
hello from org.dwwwp.test.AbstractClass

numaralandırmalar

Bu dil özelliği J2SE 5.0'da tanıtıldı . Teknik olarak numaralandırmalar, gövdesinde enum sabitleri içeren bir sınıf türüdür. Her enum sabiti, enum türünün bir örneğini tanımlar. Numaralandırma sınıfları, numaralandırma sınıfının kendisi dışında hiçbir yerde başlatılamaz.

enum Season {
    WINTER, SPRING, SUMMER, AUTUMN
}

Enum sabitlerinin, sınıf yüklendiğinde çağrılan yapıcılara sahip olmasına izin verilir:

public enum Season {
    WINTER("Cold"), SPRING("Warmer"), SUMMER("Hot"), AUTUMN("Cooler");

    Season(String description) {
        this.description = description;
    }

    private final String description;

    public String getDescription() {
        return description;
    }
}

Numaralandırmalar, sınıf gövdelerine sahip olabilir; bu durumda, numaralandırma sınıfını genişleten anonim sınıflar gibi değerlendirilirler:

public enum Season {
    WINTER {
        String getDescription() {return "cold";}
    },
    SPRING {
        String getDescription() {return "warmer";}
    },
    SUMMER {
        String getDescription() {return "hot";}
    },
    FALL {
        String getDescription() {return "cooler";}
    };
}

Arayüzler

Arayüzler , alan içermeyen ve genellikle gerçek bir uygulaması olmayan bir dizi yöntemi tanımlayan türlerdir. Herhangi bir sayıda farklı uygulamaya sahip bir sözleşme tanımlamak için kullanışlıdırlar. Her arayüz dolaylı olarak soyuttur. Arayüz yöntemlerinin, strictfpsınıflarla aynı etkiye sahip olan dil sürümüne bağlı olarak ve ayrıca staticJava SE 8'den bu yana erişim değiştiricilerinin bir alt kümesine sahip olmasına izin verilir .

interface ActionListener {
    int ACTION_ADD = 0;
    int ACTION_REMOVE = 1;
 
    void actionSelected(int action);
}

Bir arayüz uygulamak

Bir arayüz, implementsanahtar kelimeyi kullanarak bir sınıf tarafından uygulanır . Birden fazla arayüzün uygulanmasına izin verilir, bu durumda implementsvirgülle ayrılmış bir listede anahtar kelimeden sonra yazılırlar . Bir arabirim uygulayan sınıf, tüm yöntemlerini geçersiz kılmalıdır, aksi takdirde soyut olarak bildirilmelidir.

interface RequestListener {
    int requestReceived();
}

class ActionHandler implements ActionListener, RequestListener {
    public void actionSelected(int action) {
    }

    public int requestReceived() {
    }
}

//Calling method defined by interface
RequestListener listener = new ActionHandler(); /*ActionHandler can be
                                   represented as RequestListener...*/
listener.requestReceived(); /*...and thus is known to implement
                            requestReceived() method*/

Fonksiyonel arayüzler ve lambda ifadeleri

Bu özellikler Java SE 8'in piyasaya sürülmesiyle tanıtıldı. Bir arabirim, yalnızca bir yöntem tanımlarsa, otomatik olarak işlevsel bir arabirim haline gelir. Bu durumda, bir uygulama, yeni bir sınıfta uygulamak yerine bir lambda ifadesi olarak temsil edilebilir, böylece fonksiyonel tarzda kod yazmayı büyük ölçüde basitleştirir . İşlevsel arayüzlere isteğe bağlı olarak not eklenebilir @FunctionalInterface, bu da derleyiciye arayüzün gerçekten bir işlevsel arayüzün tanımına uyup uymadığını kontrol etmesini söyler.

// A functional interface
@FunctionalInterface
interface Calculation {
    int calculate(int someNumber, int someOtherNumber);
}

// A method which accepts this interface as a parameter
int runCalculation(Calculation calculation) {
    return calculation.calculate(1, 2);
}

// Using a lambda to call the method
runCalculation((number, otherNumber) -> number + otherNumber);

// Equivalent code which uses an anonymous class instead
runCalculation(new Calculation() {
    @Override
    public int calculate(int someNumber, int someOtherNumber) {
        return someNumber + someOtherNumber;
    }
})

Lambda'nın parametre türlerinin tam olarak belirtilmesi gerekmez ve uyguladığı arabirimden çıkarılabilir. Lambda'nın gövdesi return, yalnızca bir ifade ise, bir gövde bloğu ve bir ifade olmadan yazılabilir . Ayrıca, yöntemde yalnızca tek bir parametreye sahip olan arabirimler için yuvarlak parantezler atlanabilir.

// Same call as above, but with fully specified types and a body block
runCalculation((int number, int otherNumber) -> {
    return number + otherNumber;
});

// A functional interface with a method which has only a single parameter
interface StringExtender {
    String extendString(String input);
}

// Initializing a variable of this type by using a lambda
StringExtender extender = input -> input + " Extended";

Yöntem referansları

Arayüzle uyumlu adlandırılmış bir yöntem zaten varken lambda kullanmak gerekli değildir. Bu yöntem, bir yöntem referansı kullanılarak bir lambda yerine geçirilebilir. Birkaç tür yöntem referansı vardır:

Referans türü Örnek eşdeğer lambda
Statik Integer::sum (number, otherNumber) -> number + otherNumber
Ciltli "LongString"::substring index -> "LongString".substring(index)
ilişkisiz String::isEmpty string -> string.isEmpty()
sınıf oluşturucu ArrayList<String>::new capacity -> new ArrayList<String>(capacity)
Dizi oluşturucu String[]::new size -> new String[size]

Çağrılan yukarıdaki kod runCalculation, yöntem referansları kullanılarak aşağıdaki ile değiştirilebilir:

runCalculation(Integer::sum);

Miras

Arayüzler, sınıflar gibi diğer arayüzlerden miras alabilir. Sınıflardan farklı olarak, birden çok arabirimden miras almasına izin verilir. Bununla birlikte, birkaç arabirimin aynı ada sahip bir alanı olması mümkündür, bu durumda bu, erişilemeyen tek bir belirsiz üye haline gelir.

/* Class implementing this interface must implement methods of both
ActionListener and RequestListener */
interface EventListener extends ActionListener, RequestListener {    
}

Varsayılan yöntemler

Java SE 8, arayüzlere, geliştiricilerin, halihazırda arayüzü uygulayan sınıflarla uyumluluğu bozmadan mevcut arayüzlere yeni yöntemler eklemesine olanak tanıyan varsayılan yöntemleri tanıttı. Normal arabirim yöntemlerinden farklı olarak, varsayılan yöntemler, uygulayan sınıfın onu geçersiz kılmaması durumunda çağrılacak bir gövdeye sahiptir.

interface StringManipulator {
    String extendString(String input);
    
    // A method which is optional to implement
    default String shortenString(String input) {
        return input.substring(1);
    }
}

// This is a valid class despite not implementing all the methods
class PartialStringManipulator implements StringManipulator {
    @Override
    public String extendString(String input) {
        return input + " Extended";
    }
}

Statik yöntemler

Statik yöntemler, Java SE 8'de tanıtılan bir başka dil özelliğidir. Sınıflarda olduğu gibi tamamen aynı şekilde davranırlar.

interface StringUtils {
    static String shortenByOneSymbol(String input) {
        return input.substring(1);
    }
}

StringUtils.shortenByOneSymbol("Test");

Özel yöntemler

Java 9 sürümüne özel yöntemler eklendi. Bir arabirim, gövdesi özel olarak işaretlenmiş bir yönteme sahip olabilir; bu durumda, devralan sınıflar tarafından görülmez. Kodun yeniden kullanımı amacıyla varsayılan yöntemlerden çağrılabilir.

interface Logger {
    default void logError() {
        log(Level.ERROR);
    }

    default void logInfo() {
        log(Level.INFO);
    }

    private void log(Level level) {
        SystemLogger.log(level.id);
    }
}

Ek açıklamalar

Java'daki ek açıklamalar, meta verileri koda yerleştirmenin bir yoludur . Bu dil özelliği J2SE 5.0'da tanıtıldı .

Ek açıklama türleri

Java'nın bir dizi önceden tanımlanmış açıklama türü vardır, ancak yenilerini tanımlamasına izin verilir. Açıklama türü bildirimi, arabirim bildiriminin özel bir türüdür. interfaceAnahtar kelimeden önce @işaret gelmesi dışında, arayüzlerle aynı şekilde bildirilirler . Tüm ek açıklamalar dolaylı olarak genişletilir java.lang.annotation.Annotationve başka hiçbir şeyden genişletilemez.

@interface BlockingOperations {
}

Ek açıklamalar, gövdede ortak arabirimlerle aynı bildirimlere sahip olabilir, ayrıca numaralandırma ve ek açıklama içermelerine izin verilir. Temel fark, soyut yöntem bildirimlerinin herhangi bir parametre içermemesi veya istisna oluşturmamasıdır. Ayrıca default, yöntem adından sonra anahtar kelime kullanılarak bildirilen varsayılan bir değere sahip olabilirler :

@interface BlockingOperations {
    boolean fileSystemOperations();
    boolean networkOperations() default false;
}
Ek açıklamaların kullanımı

Açıklamalar, paket, sınıf (enumlar dahil), arayüz (açıklamalar dahil), alan, yöntem, parametre, yapıcı veya yerel değişken olsun, herhangi bir bildirimde kullanılabilir. Ayrıca enum sabitleri ile kullanılabilirler. Detaylandırmalar, @detaylandırma tipi adından önceki işaret kullanılarak bildirilir , bundan sonra eleman-değer çiftleri parantez içinde yazılır. Varsayılan değeri olmayan tüm öğelere bir değer atanmalıdır.

@BlockingOperations(/*mandatory*/ fileSystemOperations,
/*optional*/ networkOperations = true)
void openOutputStream() { //Annotated method
}

Genel formun yanı sıra, bir açıklama bildirmek için stenografi olan iki başka form daha vardır. İşaretleyici açıklaması kısa bir biçimdir, öğelere hiçbir değer atanmadığında kullanılır:

@Unused // Shorthand for @Unused()
void travelToJupiter() {
}

Diğer kısa biçim, tek öğeli açıklama olarak adlandırılır . Yalnızca bir öğe içeren açıklama türleriyle veya birden çok öğenin mevcut olduğu, ancak yalnızca bir öğenin varsayılan bir değere sahip olmadığı durumlarda kullanılır. Tek öğe açıklama formunda öğe adı atlanır ve bunun yerine yalnızca değer yazılır:

/* Equivalent for @BlockingOperations(fileSystemOperations = true).
networkOperations has a default value and
does not have to be assigned a value */

@BlockingOperations(true)
void openOutputStream() {
}

jenerik

Jenerikler veya parametreli tipler veya parametrik polimorfizm , J2SE 5.0'da tanıtılan başlıca özelliklerden biridir . Jenerikler tanıtılmadan önce, tüm türleri açıkça belirtmek gerekiyordu. Jenerik ilaçlarla, kesin tip belirtmeden farklı tiplerle benzer şekilde çalışmak mümkün hale geldi. Jeneriklerin temel amacı, tür güvenliğini sağlamak ve derleme sırasında çalışma zamanı hatalarını tespit etmektir. C#'tan farklı olarak, silme türünden dolayı kullanılan parametrelerle ilgili bilgiler çalışma zamanında mevcut değildir .

Genel sınıflar

Sınıflar , sınıf adından sonra köşeli parantezler ( <ve >) içine bir tür değişkeni eklenerek parametrelenebilir . Bu tür değişkenin gerçek türler yerine sınıf üyelerinde kullanılmasını mümkün kılar. Birden fazla tip değişken olabilir, bu durumda bunlar virgülle ayrılmış bir listede bildirilir.

Bir tür değişkenini belirli bir sınıfın alt türüyle sınırlamak veya tür tarafından uygulanması gereken bir arabirim bildirmek mümkündür. Bu durumda tür değişkenine extendsanahtar kelime ve ardından sınıfın veya arabirimin adı eklenir . Değişken hem sınıf hem de arabirim tarafından sınırlandırılmışsa veya birkaç arabirim varsa, önce sınıf adı, ardından & sınırlayıcı olarak kullanılan işaretli arabirim adları yazılır .

/* This class has two type variables, T and V. T must be 
a subtype of ArrayList and implement Formattable interface */
public class Mapper<T extends ArrayList & Formattable, V> {
    public void add(T array, V item) {
        // array has add method because it is an ArrayList subclass
        array.add(item);
    }
}

Parametreli türde bir değişken bildirildiğinde veya bir örnek oluşturulduğunda, türü tam olarak sınıf başlığındakiyle aynı biçimde yazılır, ancak gerçek tür, tür değişkeni bildiriminin yerine yazılır.

/* Mapper is created with CustomList as T and Integer as V.
CustomList must be a subclass of ArrayList and implement Formattable */
Mapper<CustomList, Integer> mapper = new Mapper<CustomList, Integer>();

Java SE 7'den beri <>, tür argümanları yerine bir elmas ( ) kullanmak mümkündür , bu durumda ikincisi çıkarılacaktır. Java SE 7'deki aşağıdaki kod, önceki örnekteki koda eşdeğerdir:

Mapper<CustomList, Integer> mapper = new Mapper<>();

Parametreli bir tür için bir değişken bildirirken, açık tür adları yerine joker karakterler kullanmak mümkündür. Joker karakterler ?, gerçek tür yerine işaret yazılarak ifade edilir . Olası türleri belirli bir sınıfın alt sınıfları veya üst sınıfları ile sınırlamak, extendsanahtar kelimeyi veya superanahtar kelimeyi ve ardından sınıf adını yazarak sınırlandırmak mümkündür .

/* Any Mapper instance with CustomList as the first parameter
may be used regardless of the second one.*/
Mapper<CustomList, ?> mapper;
mapper = new Mapper<CustomList, Boolean>();
mapper = new Mapper<CustomList, Integer>();

/* Will not accept types that use anything but
a subclass of Number as the second parameter */
void addMapper(Mapper<?, ? extends Number> mapper) {
}

Genel yöntemler ve yapıcılar

Jeneriklerin kullanımı bazı belirli yöntemlerle sınırlı olabilir, bu kavram kurucular için de geçerlidir. Parametreli bir yöntem bildirmek için, tür değişkenleri, genel sınıflarla aynı biçimde, yöntemin dönüş türünden önce yazılır. Yapıcı durumunda, tür değişkenleri yapıcı adından önce bildirilir.

class Mapper {
    // The class itself is not generic, the constructor is
    <T, V> Mapper(T array, V item) {
    }
}

/* This method will accept only arrays of the same type as
the searched item type or its subtype*/
static <T, V extends T> boolean contains(T item, V[] arr) {
    for (T currentItem : arr) {
        if (item.equals(currentItem)) {
            return true;
        }
    }
    return false;
}

Genel arayüzler

Arayüzler, sınıflara benzer şekilde parametrelendirilebilir.

interface Expandable<T extends Number> {
    void addItem(T item);
}

// This class is parameterized
class Array<T extends Number> implements Expandable<T> {
    void addItem(T item) {
    }
}

// And this is not and uses an explicit type instead
class IntegerArray implements Expandable<Integer> {
    void addItem(Integer item) {
    }
}

Ayrıca bakınız

Referanslar

Dış bağlantılar