Java'da otomatik tür çıkarımı var mı?


113

autoJava'da C ++ 'da olduğu gibi bir değişken türü var mı?

Bir örnek:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Java'da geliştirilmiş bir for döngüsü olduğunu biliyorum, ancak bir otomatik var mı? Değilse, bunu yapmak için bir hack var mı? C ++ 11'deki yeni özelliğe atıfta bulunuyorum


1
Temel türler dışındaki her şey bir tür değişkenine atanabilir Object, bu nedenle bazı işlemler için Objectistediğiniz yerde kullanabilirsiniz auto.
Zyx 2000

1
hiçbir
java'nın

@ Zyx2000: O zaman, to_stringsöz konusu gerçek nesneyi değil nesnenin işlevini kullanacak , değil mi?
Games Brainiac

2
@GamesBrainiac: Hayır, varsa geçersiz kılınan sürümü kullanacaktır.
Keppil

2
Aradığınız terim "otomatik" değil, "tür çıkarımı". Java'da tür çıkarımı hakkında epeyce soru var, ancak çoğunlukla jeneriklere atıfta bulunuyorlar, bu yüzden bir kopyasını nasıl bulacağımı

Yanıtlar:


49

Soru DÜZENLENMEDEN önce cevaplandı :

autoJava'da değişken türü yoktur . Aynı döngü şu şekilde elde edilebilir:

for ( Object var : object_array)
  System.out.println(var);

Java, kapsamı tanımlandıkları blok içinde olan yerel değişkenlere sahiptir. C ve C ++ 'ya benzer, ancak auto veya register anahtar sözcüğü yoktur. Bununla birlikte, Java derleyicisi açıkça başlatılmamış bir yerel değişkenin kullanımına izin vermez ve bir derleme hatası verir (derleyicinin genellikle yalnızca bir uyarı vereceği C ve C ++ 'dan farklı olarak). Nezaket: Wikipedia .

Hayır, Java'da C ++ gibi herhangi bir genel tür çıkarımı yoktur. Bir RFE vardı ancak bu " Düzeltilmeyecek " olarak kapatıldı, verilen neden şuydu:

İnsanlar, tip bildiriminin fazlalığından iki şekilde yararlanır. İlk olarak, fazlalık tür değerli bir belge işlevi görür - okuyucuların, hangi tür döndürdüğünü bulmak için getMap () bildirimini aramasına gerek yoktur. İkincisi, artıklık, programcının amaçlanan türü bildirmesine ve böylece derleyici tarafından gerçekleştirilen çapraz kontrolden yararlanmasına izin verir.


10
@GamesBrainiac Hayır, yöntem çağrıları Java'da her zaman polimorfiktir. Ancak diğer birçok şey (örneğin aşırı yük çözümü veya tanımlanmamış herhangi bir işlem Object) bu şekilde yapılamaz. Bu gerçekten iyi bir cevap değil, sadece sorudaki örnek zayıf olduğu için işe yarıyor.

10
Bu soru, C ++ 11'deki tür çıkarımı ile ilgilidir auto, C ve C ++ 11 öncesi kullanımıyla ilgili değildir . Düzenlemeniz konu dışı.

4
"Demek istediğim bu değil, onu bir Nesneye çevirmeyi yazdığınızda, size Object'in to_string'ini verecek" False. Kesinlikle% 100 yanlış.
Louis Wasserman

140
"İnsanlar fazlalıktan yararlanır." Bu doğru. Her sabah uyanıyorum ve "kodumu nasıl daha fazla gereksiz hale getirebilirim?" Diye düşünüyorum. Faydalarından dolayı.
ahoffer

2
Üstelik bu yanıt eski çünkü varJava 9'dan beri ayrılmış bir anahtar kelimedir.
6infinity8

69

Java 10, varanahtar kelime aracılığıyla sizin (ve benim) istediğiniz şeye sahip olabilir .

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

Gönderen JDK Geliştirme Önerileri 286


Güncelleme: Yap, bu özellik onu Java 10 sürümüne dahil etti!


6
Bu bir gelişme, ancak bu anahtar kelime yalnızca yerel değişkenlerle çalışabilir. C ++ otomatik tür çıkarımı kadar güçlü değil
texasbruce

7
Minor nit-pick: varbir anahtar kelime değildir! Gönderen JLS : "var bir anahtar kelime değil, yerel bir değişken bildiriminde türü olarak özel anlamı olan bir tanımlayıcı değil". Bu nedenle, anahtar kelimelerin aksine, bir değişkeni veya bir yöntemi "var" çağırmanızı engelleyecek hiçbir şey yoktur.
Klitos Kyriacou

2
İyi nokta @KlitosKyriacou. Yine de, "anahtar kelime" yi "tanımlayıcı" ile değiştirmeyi hayal edersem - veya hatta "yerel değişken bildiriminin türü olarak özel anlam taşıyan tanımlayıcı" - yanıtın daha az net olacağını düşünüyorum. Ama evet, vargerçekten de anahtar kelime listesinde yok.
özür dilerimmissjackson

Yalnızca geriye dönük uyumluluk için bir anahtar kelime değildir. Bu isimde bir tanımlayıcıya sahip olabileceğiniz gerçeğinin yanı sıra, var bir anahtar kelime görevi de görür.
facetus

25

Java 7, elmas sözdizimini sunar

Box<Integer> integerBox = new Box<>(); // Java 7

Eski java ile karşılaştırıldığında

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

Eleştirel okuyucu, bu yeni sözdiziminin orijinal soruda for döngülerinin yazılmasına yardımcı olmadığını fark edecektir. Bu doğru ve tamamen kasıtlı görünüyor. Oracle'ın hata veritabanına atıfta bulunan diğer yanıta bakın.


4
Doğru, ama onun (ve benim) aradığı şey auto integerBox = new Box<Integer>();HashMap<String, LinkedList<Operation, Set<Integer>>>
şuna

1
Bu endişe, kod örneklerinden sonra bahsettiğim şeydir. Sonuç, Java'nın bunu yapmadığı ve bunun kasıtlı olduğuydu.
Tarrasch

18

Java 8'de, türü bildirmekten kaçınmak için lambda tür çıkarımını kullanabilirsiniz. Soruyu soranın örneklerinin analogu şöyle olacaktır:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

her ikisi de yöntem referansları kullanılarak basitleştirilebilir:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

8

Kısacası, hayır, otomatik tip yoktur. Tek yaptığınız değeri yazdırmaksa, değere sadece Object.


ya da hesaplama hashCodeya da sınıf isimlerini toplama ya da ... fikri anladınız;) Liste kısa olsa da. Nesne sınıfı belgelerine bakın (yorum yeni başlayanlar içindir, eminim bunu biliyorsunuzdur SimonC)
Alexander Malakhov

4

Bu saf bir Java çözümü değildir, ancak lombok adlı bir kitaplık eklemek aşağıdaki sihrin autoC ++ 'daki anahtar kelimeye çok benzer şekilde derlenmesini ve çalışmasını sağlar.

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.