C # içinde var anahtar sözcüğünün bir kullanımı örtük tür bildirimidir. İçin Java eşdeğer sözdizimi nedir var ?
C # içinde var anahtar sözcüğünün bir kullanımı örtük tür bildirimidir. İçin Java eşdeğer sözdizimi nedir var ?
Yanıtlar:
Hiç yok. Ne yazık ki, tam tip adını yazmanız gerekiyor.
Düzenleme: Gönderildikten 7 yıl sonra var
, Java 10'da yerel değişkenler için (ile ) tür çıkarımı eklendi.
Düzenleme: Gönderildikten 6 yıl sonra, aşağıdan bazı yorumları toplamak için:
C # var
anahtar sözcüğüne sahip olmasının nedeni , .NET'te adı olmayan Türlere sahip olmanızdır. Örneğin:
var myData = new { a = 1, b = "2" };
Bu durumda, uygun bir tip vermek imkansız olacaktır myData
. 6 yıl önce, Java'da bu imkansızdı (son derece ayrıntılı ve tuhaf olsalar bile, tüm Türlerin isimleri vardı). Bunun bu arada değişip değişmediğini bilmiyorum.
var
ile aynı değildir dynamic
. var
iable'lar hala% 100 statik olarak yazılmıştır. Bu derlenmeyecektir:
var myString = "foo";
myString = 3;
var
tür bağlamdan açık olduğunda da kullanışlıdır. Örneğin:
var currentUser = User.GetCurrent();
Sorumlu olduğum herhangi bir kodda, currentUser
içinde bir User
veya türetilmiş sınıf olduğunu söyleyebilirim. Açıkçası, eğer User.GetCurrent
bir int dönüşü uygulama , o zaman belki bu sizin için zararlıdır.
Bunun bir ilgisi yok var
, ancak yöntemleri diğer yöntemlerle (örn. new public void DoAThing()
) Gölgelediğiniz garip kalıtım hiyerarşileriniz varsa , sanal olmayan yöntemlerin, kullanıldıkları Türden etkilendiğini unutmayın.
Bunun iyi bir tasarımın göstergesi olduğu gerçek bir dünya senaryosu hayal edemiyorum, ancak bu beklediğiniz gibi çalışmayabilir:
class Foo {
public void Non() {}
public virtual void Virt() {}
}
class Bar : Foo {
public new void Non() {}
public override void Virt() {}
}
class Baz {
public static Foo GetFoo() {
return new Bar();
}
}
var foo = Baz.GetFoo();
foo.Non(); // <- Foo.Non, not Bar.Non
foo.Virt(); // <- Bar.Virt
var bar = (Bar)foo;
bar.Non(); // <- Bar.Non, not Foo.Non
bar.Virt(); // <- Still Bar.Virt
Belirtildiği gibi, sanal yöntemler bundan etkilenmez.
Hayır, var
gerçek değişken olmadan başlatmak için beceriksiz bir yol yoktur .
var foo1 = "bar"; //good
var foo2; //bad, what type?
var foo3 = null; //bad, null doesn't have a type
var foo4 = default(var); //what?
var foo5 = (object)null; //legal, but go home, you're drunk
Bu durumda, sadece eski moda bir şekilde yapın:
object foo6;
var p = new X(); p.Z()
değildir, bu yüzden ... SuperX p = new X(); p.Z()
tüm X ve ve SuperX ile aynı değildir X : SuperX
. İle statik Çeşidi daima ama daima, yukarıdaki ilk örnekte ikinci örnekteki. Dikkat edilmesi gereken ince ama önemli bir fark. Ama cevabınız çok doğru :-)var
p
X
SuperX
var
kodu daha az netleştirmez. Bence tam tersi. Örneğin, türünü bildirip başlatırken ( RadioButton radioButton = new RadioButton();
) neden aynı satıra iki (hatta üç) kez yazıyorsunuz ? var
değişkenlerinizi adlandırırken iki kez düşünmeyi tercih eder, çünkü odağı türden ziyade işlevselliğe dönüştürür (örneğin, UserCollection collection = new userRepository.GetUsers();
daha doğal olarak dönüşür var users = userRepository.GetUsers();
). Eğer var
belirsiz olduğunu düşünüyorsanız , bunun nedeni kullanılmamış olmasıdır.
var
kesinlikle kodun iyi kullanılmasını sağlayabilir, ama aynı zamanda çok kötü kullanılmasını da belirsiz hale getirebilir; birçok biçimlendirme seçeneği gibi. Denge, her ikisi de .NET 1.0'da bulunmayan anonim nesneleri ve jenerikleri ne kadar kullandığınıza bağlı olarak değişir ve C♯'nin ilk sürümünde varsayımsal bir anahtar kelime olarak daha az kullanışlı hale gelir. RadioButton
radioButton
Düğmeye ilişkin önemli olan tek şeyin a olduğu bir fabrika veya yardımcı yöntem söz konusu olduğunda yalnızca bir ad verirdim RadioButton
, aksi takdirde bu olan veya olmayan delilik var
.
var
senin kadar eleştireldim , daha fazla olmasa da, fikrimi değiştirdim ve belki de farklı görüşler sorusu kadar basit, çünkü bunun bir şey olduğunu söylediğinde hala yanlış olduğunu düşünüyorum. anonim nesneleri ve jenerikleri ne kadar kullandığınız önemli değildir;) Tip bildirimi çoğunlukla sadece kod gürültüsüdür, kod olmadan anlayamıyorsanız, kod her iki durumda da muhtemelen belirsizdir.
var
kendisi derleyiciden türü atamadan çıkarmasını ister; sözdizimsel şeker. İlk başta şüpheliydim, ama dini olarak kullanıyorum ve henüz karışıklığa neden olduğu bir zamanla karşılaşmadım. Örnekleme yapılırken fazlalığı ortadan kaldırır ve referans verirken türü kontrol etme ihtiyacını ortadan kaldırır. JAVA 9'dan itibaren JAVA eşdeğeri yoktur.
Projenize Lombok eklerseniz, val anahtar sözcüğünü kullanabilirsiniz .
final
mutlaka değiştirilemeyen nesneler . Düşününfinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.html
JEP - JDK Geliştirme-Teklif
http://openjdk.java.net/jeps/286
JEP 286: Yerel Değişken Türü Çıkarım
Yazar Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
IntelliJ için bir şekilde - var
Java ile size bir eklenti hazırladım . Bu bir hack, bu yüzden olağan feragatnameler geçerlidir, ancak Java geliştirmeniz için IntelliJ kullanıyorsanız ve denemek istiyorsanız, https://bitbucket.org/balpha/varsity adresindedir .
JDK 10'un 20 Mart'ta piyasaya sürülmesiyle, Java artık JEP 286'davar
belirtildiği gibi ayrılmış bir tür adı (anahtar kelime değil - aşağıya bakın) içerir . Yerel değişkenler için Java 10 veya sonraki sürümlerde şu anda geçerlidir:
var map = new HashMap<String, Integer>();
var
Java ayrılmış tür adı neredeyse aynıdır var
hem örtük tiplemesi için (önemli farklar için aşağıya bakınız) izin vermesini de C # anahtar kelime. var
Java'da yalnızca aşağıdaki bağlamlarda ( JEP 286: Hedeflerde numaralandırıldığı gibi) örtük tür çıkarımı için kullanılabilir :
Bu nedenle var
olamaz alanlar, dönüş türleri, sınıf adları veya arayüz adları için kullanılabilir. Gerekçesi, JEP 286'da (Brian Goetz tarafından yazılan) belirtildiği gibi, yerel değişkenleri bildirirken ve tanımlarken uzun tip adlarının dahil edilmesi ihtiyacını ortadan kaldırmaktır :
Java kodunun yazılmasıyla ilişkili töreni azaltarak, Java'nın statik tip güvenliğe olan bağlılığını koruyarak, geliştiricilerin yerel değişken türlerinin genellikle gereksiz bildirimlerini kullanmasına izin vererek geliştirici deneyimini geliştirmeye çalışıyoruz.
var
Java'da kapsam belirlemevar
Java'da bir anahtar kelime değil, ayrılmış bir tür adı olduğuna dikkat edilmelidir . JEP 286'dan alıntılandığı gibi:
Var tanımlayıcısı bir anahtar kelime değildir; bunun yerine ayrılmış bir tür adıdır. Bu, değişken, yöntem veya paket adı olarak var kullanan kodun etkilenmeyeceği anlamına gelir; sınıf veya arabirim adı olarak var kullanan kod etkilenir (ancak bu adlar alışılmış adlandırma kurallarını ihlal ettikleri için uygulamada nadirdir).
var
Anahtar sözcük değil, ayrılmış bir tür adı olduğundan , paket adları, yöntem adları ve değişken adları için de kullanılabilir (yeni tür parazit rolüyle birlikte). Örneğin, aşağıdakiler var
Java'nın geçerli kullanımlarına ilişkin örneklerdir :
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
JEP 286'dan alıntılandığı gibi:
Bu tedavi, başlatıcılarla yerel değişkenlerle, gelişmiş for-loop'taki indekslerle ve geleneksel for-loop'ta beyan edilen yerellerle sınırlı olacaktır; yöntem formları, yapıcı formları, yöntem döndürme türleri, alanlar, yakalama formları veya başka herhangi bir değişken bildirimi için kullanılamaz.
var
Java & C Arasındaki FarklarBu var
C # ve Java arasındaki önemli bir fark aşağıdakileri içerir: var
C # 'da bir tür adı olarak kullanılabilir, ancak Java'da bir sınıf adı veya arabirim adı olarak kullanılamaz. Göre C # belgelerine (Dolaylı olarak Yazılan Yerel Değişkenler) :
Adlandırılmış bir tür
var
kapsamdaysa,var
anahtar kelime bu tür adına çözümlenir ve örtük olarak yazılan bir yerel değişken bildiriminin parçası olarak değerlendirilmez.
var
C # 'da bir tür adı olarak kullanılabilmesi , bazı karmaşıklıklar yaratır ve var
Java'da var
bir sınıf veya arabirim adı olarak izin vermeyerek kaçınılması gereken bazı karmaşık çözünürlük kurallarını getirir . var
C # 'da tür adlarının karmaşıklığı hakkında bilgi için , bkz. Kısıtlanmış türdeki değişken bildirimleri için kısıtlamalar geçerlidir . `Var in Java için kapsam belirleme kararının ardındaki mantık hakkında daha fazla bilgi için, bkz. JEP 286: Kapsam Belirleme Seçenekleri .
var
alanlar veya dönüş türleri için kullanamayacağınız bir fark var mı ? Not etmek neden önemlidir?
var
Java'da alanlar veya dönüş türleri için kullanılamaz. Bu önemlidir, çünkü bu kısıtlama var
bağlamı hassas hale getirir , burada sadece bazı bağlamlarda (yerel değişkenler) kullanılabilir, diğerleri değil. Bu mutlaka Java ve C # arasında dikkat edilmesi gereken bir fark değil var
, Java'da kullanılırken genel olarak önemli bir kısıtlamadır .
var
bir sınıf adı yapmak ve bu şekilde kullanabilirsiniz. Teknik olarak c # durumunda bir "bağlam anahtar kelimesi" dir, ancak Java'da aynı şeyi yapamazsınız. Yanlışsam düzelt.
var
bir sınıf adı veya (yaygın zaten değildir) Java arabirim adı olarak, ancak değişken isimler, yöntem adları ve paket isimleri için kullanabilirsiniz. Örneğin, var var = 1;
geçerli bir Java deyimi ancak bir sınıf bildirmek için çalışıyor olduğu public class var {}
hatayla sonuçları: as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
. var
Java'daki mantık ve var
C # ile arasındaki farklar hakkında daha ayrıntılı bilgi almak için yukarıdaki cevabı güncelledim .
JDK 10'da desteklenecek. Erken erişim derlemesinde çalışırken görmek bile mümkün .
JEP 286 :
Başlatıcılarla yerel değişkenlerin bildirimlerine yazılan çıkarımları genişletmek için Java Dili'ni geliştirin.
Şimdi yazmak yerine:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Sen yaz:
var list = new ArrayList<String>();
var stream = myStream();
Notlar:
var
şimdi ayrılmış bir tür adıYerel sisteminize Java'yı yüklemeden denemek istiyorsanız, üzerinde JDK 10 yüklü bir Docker görüntüsü oluşturdum :
$ docker run -it marounbassam/ubuntu-java10 bash
root@299d86f1c39a:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> var list = new ArrayList<String>();
list ==> []
var
) eşdeğer değildir. Olarak var
örneğin list
tiptedir ArrayList
, bir değil List
.
Basit bir çözüm (iyi bir IDE kullandığınızı varsayarsak), sadece her yere 'int' yazmanız ve ardından türü sizin için ayarlamanızdır.
Aslında 'var' adında bir sınıf ekledim, bu yüzden farklı bir şey yazmak zorunda değilim.
Kod hala çok ayrıntılı, ama en azından yazmak zorunda değilsiniz!
int
) - Bir şey mi kaçırıyorum? (*: Eclipse'e asla iyi bir IDE
Java 10 yerel değişken tipi çıkarım elde etti, bu yüzden şimdi var
C # bir (ben bildiğim kadarıyla) hemen hemen eşdeğer vardır.
Ayrıca, kınamayan türleri de çıkarabilir (programcı tarafından o yerde adlandırılamayan türler ; ancak hangi türlerin kınanamaz olduğu farklıdır). Örneğin bkz . İş yerinde asla kullanmamanız gereken hileler var
ve anonim sınıflar .
Bulabildiğim tek fark C # 'da,
Java 10'da var
yasal bir tür adı yoktur.
Java 10 itibariyle eşdeğerdir ... var
.
Bu eski olduğunu biliyorum ama neden bir var sınıf oluşturmak ve farklı türleri ile yapıcılar oluşturmak ve hangi yapıcıların çağrıldığına bağlı olarak farklı türü ile var olsun. Bir türü diğerine dönüştürmek için yöntemler de oluşturabilirsiniz.
Lombok
var destekler ancak hala deneysel olarak sınıflandırılır:
import lombok.experimental.var;
var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);
İşte onu kullanmaya çalışırken kaçınmak için bir tuzak IntelliJ IDEA
. Otomatik tamamlama ve her şey dahil olmak üzere beklendiği gibi çalışıyor gibi görünüyor. "Kesintisiz" bir çözüm olana kadar (örneğin, JEP 286: Yerel Değişken Türü Çıkarım nedeniyle ), bu şu anda en iyi bahsiniz olabilir.
Bir değişiklik yapmadan veya oluşturmadan da val
destek olduğunu unutmayın .Lombok
lombok.config
Java 10'da, ancak yalnızca Yerel değişkenler için ,
Yapabilirsin,
var anum = 10; var aString = "Var";
Ama yapamam,
var anull = null; // Since the type can't be inferred in this case
Daha fazla bilgi için teknik özelliklere göz atın .
var
yakalama türleri, kavşak türleri ve anonim sınıf türleri dahil olmak üzere birçok türden ifade edilemeyen tür için kullanılabilir. Java 11'den itibaren lambda parametrelerine de uygulanabilir.
Genel olarak herhangi bir tür için Object sınıfını kullanabilirsiniz, ancak daha sonra tür dökümünü yapmalısınız!
Örneğin:-
Object object = 12;
Object object1 = "Aditya";
Object object2 = 12.12;
System.out.println(Integer.parseInt(object.toString()) + 2);
System.out.println(object1.toString() + " Kumar");
System.out.println(Double.parseDouble(object2.toString()) + 2.12);
var
Şimdi resmi olarak dilde olan kelimeyle, cevabınız da şimdi eski moda yoldan bahsediyor.
Bu özellik artık Java SE 10'da mevcut. Statik, güvenli tipli var nihayet java dünyasına dönüştü :)
kaynak: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(veyavar
) belirli bir "Java değiştirme" dili kullanıyorsanız ;-)