Java sözdizimi - Java syntax
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:
- Harf ( Romen rakamları gibi sayısal harfler dahil ) veya rakam olan herhangi bir Unicode karakteri .
- Para birimi işareti (¥ gibi).
- Bağlantı noktalama karakteri ( _ gibi ).
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
throwvecatchtablolar.
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ıflarfinalgeniş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 |
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. İçinsynchronizedyöntemlerle monitör sınıfı örneğidir veyajava.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şsevolatile, 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
- Patrick Naughton , Herbert Schildt . Java 2: Tam Referans , üçüncü baskı. McGraw-Hill Şirketleri, 1999. ISBN 0-07-211976-4
- Vermeulen; Ambler; Bumgardner; Metz; Misfeldt; Şur; Thompson (2000). Java Stilinin Öğeleri . Cambridge Üniversitesi Yayınları. ISBN'si 0-521-77768-2.
- Gosling, James ; Sevinç, Bill ; Çelik, Guy ; Bracha, Gillad (2005). Java Dili Belirtimi (3. baskı). Addison-Wesley Profesyonel . 2008-12-03 alındı .
Dış bağlantılar
- Java Dili Belirtimi, Üçüncü baskı Java dilinin yetkili açıklaması
- Java SE 10 API Javadoc'ları