Java Void Referans Türü için kullanılır mı?


163

Java Void- büyük harf V-- referans türü vardır . Şimdiye kadar kullanılan gördüğüm tek durum parametreleştirmenin olduğunu Callables

final Callable<Void> callable = new Callable<Void>() {
            public Void call() {
                foobar();
                return null;
            }
        };

Java Voidbaşvuru türünün başka kullanımları var mı? Hiç başka bir şey atanabilir nullmi? Evet ise, örnekleriniz var mı?



Yanıtlar:


116

Voidilgilenmediğiniz jenerik bir argüman için kongre haline gelmiştir. Anlaşılamayan başka türler kullanmanız için hiçbir neden yoktur System.

Ayrıca, örneğin Mapdeğerlerde de kullanılır (ancak harita olarak Collections.newSetFromMapkullanımların değerleri Booleankabul etmesi gerekmez null) ve java.security.PrivilegedAction.

Üzerine bir web günlüğü girişi yazdımVoid geri birkaç yıl.


bu sözleşmeyi kim yaptı? docs, docs.oracle.com/javase/tutorial/java/generics/types.html "Tür Parametresi Adlandırma Kuralları" Kural olarak , tür parametre adları tek, büyük harflerdir. "
barlop

4
@barlop Bu parametre adı değil argüman. Yani, türdür java.lang.Void. Josh Bloch, konvansiyonu popülerleştirdi, ancak bir kez gördüğünüzde, bu bariz bir seçimdir.
Tom Hawtin - taktik

2
Bu blog girişi öldü
mFeinstein

51

Yansımaları kullanarak Void örneği oluşturabilirsiniz, ancak bunlar hiçbir şey için yararlı değildir. Void, genel bir yöntemin hiçbir şey döndürmediğini belirtmenin bir yoludur.

Constructor<Void> constructor = Void.class.getDeclaredConstructor();
constructor.setAccessible(true);
Void v = constructor.newInstance();
System.out.println("I have a " + v);

gibi bir şey yazdırır

I have a java.lang.Void@75636731

22
Belgelerin söylediği bir sınıfı somutlaştırılamadığı için örnek oluşturmak için +1. Bunu ben de yaptım ve somutlaşmış Boşlukların işe yaramaz olduğuna katılıyorum.
Luke Woodward

1
Yapıcı <Void> cv = Void.class.getDeclaredConstructor (); cv.setAccessible (doğru); Void v = cv.newInstance (); System.out.println (h); //;)
Peter Lawrey

Bir alıştırma olarak, yansımaları kullanarak yeni bir Sınıf oluşturmayı deneyin ve ne olduğunu görün.
Peter Lawrey

Sun.reflect.InstantiationExceptionConstructorAccessorImpl bir java.lang.InstantiationException aldım. :(
Luke Woodward

7
Bu uygulamaya özeldir ve herhangi bir zamanda değişebilir. Sınıfın arg-yapıcı bir kurucuya sahip olduğuna ve herhangi bir şey yapabilecek birine sahip olsa bile (belki de System.exit(0)) bir garanti yoktur . Ben bir yapıcı ile yarar sınıfları yazma eğilimindedir private Void() { throw new Error(); }. Bazıları değersiz bir numaralandırma tercih edebilir.
Tom Hawtin - tackline


19

Kamu kurucuları olmadığı göz önüne alındığında, ona başka bir şey verilemeyeceğini söyleyebilirim null. Ben sadece örnekte gösterildiği gibi "Bu genel parametre kullanmanıza gerek yok" için bir yer tutucu olarak kullandım.

Javadoc'un söylediklerinden yansımada da kullanılabilir :

Void sınıfı, Java anahtar sözcüğü void'ini temsil eden Class nesnesine bir başvuru içeren, örneklenemez bir yer tutucu sınıftır.


Oracle / Sun'ın bu şekilde tanımlandığını görmek için yeterince komik, null her türden bir örnektir. Her neyse, dediğin gibi, bunun saf anlamı "Ben burada ilgilenmiyorum gibi herhangi bir tür yazabilirim, bu yüzden kodumu okuyan insanların tam olarak anladığından emin olmak için Void koyacağım"
Snicolas

17

Tüm ilkel sarma sınıfları ( Integer, Byte, Boolean, Double, vs.), statik karşılık gelen ilkel sınıfına ilişkin bir referansın içeren TYPE, örneğin: alanına

Integer.TYPE == int.class
Byte.TYPE == byte.class
Boolean.TYPE == boolean.class
Double.TYPE == double.class

Voidbaşlangıçta voidtüre referans vermek için bir yerde oluşturuldu :

Void.TYPE == void.class

Ancak, kullanarak hiçbir şey kazanamazsınız Void.TYPE. Kullandığınızda void.class, bu voidtür bir şey yaptığınız çok daha açıktır .

Bir kenara, son denediğimde BeanShell tanımadı void.class, bu yüzden orada kullanmalısın Void.TYPE.


8
Yani hem Void.class hem de void.class var!
Tom Anderson

8

Kullandığınızda ziyaretçi desen o emin dönüş değeri sıfır olacağından olmak istediğinizde süpürge yerine Nesne Void kullanmak olabilir

Misal

public interface LeavesVisitor<OUT>
{
   OUT visit(Leaf1 leaf);

   OUT visit(Leaf2 leaf);
}

Ziyaretçinizi uygulayacağınız zaman, ÇIKIŞI açıkça Geçersiz olarak ayarlayabilirsiniz, böylece ziyaretçinizin Object kullanmak yerine her zaman null değerini döndüreceğini bilirsiniz

public class MyVoidVisitor implements LeavesVisitor<Void>
{
    Void visit(Leaf1 leaf){
        //...do what you want on your leaf
        return null;
    }

    Void visit(Leaf2 leaf){
        //...do what you want on your leaf
        return null;
    }
}

5

Jeneriklerden önce, yansıma API'sı için, diğer ilkel tür sınıflarına karşılık gelen bir void yöntemi için Method.getReturnType () tarafından döndürülen TYPE'yi tutmak için oluşturuldu.

EDIT: JavaDoid of Void: "Void sınıfı, Java anahtar sözcüğü void temsil eden Class nesnesine bir başvuru tutmak için örneksiz bir yer tutucu sınıfıdır". Generics'ten önce, yansıma dışında bir faydasının farkında değilim.


Buna inanmıyorum. Şu an önümde 1.4 veya daha eski bir JVM yok, ancak Method.getReturnType () her zaman void.class void.class için döndü inanıyorum.
Luke Woodward

@Pour: Ben jeneriklerden önce , farkında olduğum tek kullanımın bir void yöntemi için yansıma Method.getReturnType () kullanılan TYPE (Void.TYPE gibi) tutmak olduğunu söylüyorum.
Lawrence Dol

Bir şekilde geri dönmüyor Void. Lütfen stackoverflow.com/questions/34248693/…
Alireza Fattahi

3

Void'i başlatamadığınız için Apache commons Null nesnesini kullanabilirsiniz ,

Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;

ilk satırda bir nesneniz var, bu nedenle aNullObject != nulltutar, ikinci satırda referans yok, yani noObjectHere == nulltutar

Posterin asıl sorusunu cevaplamak için bunun kullanımı, tamamen farklı olan "hiçbir şey" ile "hiçbir şey" arasında ayrım yapmaktır.

Not: Boş nesne desenine hayır deyin


1

Void, ilkel void tipini sarmak için oluşturulur. Her ilkel tipin karşılık gelen Referans tipi vardır. Void, genel bir sınıfı veya genel bir yöntemi kullanmak için kullanılır, İlgilenmediğiniz bir genel argümanlar cadı ve işte bir örnek ...

public void onNewRegistration() {
    newRegistrationService.createNewUser(view.getUsername(), view.getPassword(),
            view.getInitialAmount(), view.getCurrency(), new AsyncCallback<Void>() {
      @Override
      public void onFailure(Throwable caught) {

      }

      @Override
      public void onSuccess(Void result) {
        eventBus.fireEvent(new NewRegistrationSuccessEvent());
      }
    });
  } 

Burada, gördüğünüz gibi, ben yeni kayıtlar oluşturmak istediğim sunucudan hiçbir şey istemiyorum, ama public interface AsyncCallback<T> { .... }genel bir arayüz yani jenerik ilkel türleri kabul etmiyorum çünkü Void sağlamak


0

Ayrıca, bir Attachmentnesneye ihtiyaç duymadığınızda Async-IO tamamlama geri çağrılarında yaygın olarak kullanılır . Bu durumda G / Ç işlemi için null değerini belirtir ve uygularsınız CompletionHandler<Integer,Void>.


0

Nadir bir durum olabilir ama bir kez Voiden boy sınıflarında kullandım.

Bu, @Logek açıklama içeren yöntemlerden sonra çalışan ve döndürülen yöntemi ve yöntem döndürme türü geçersiz değilse bazı bilgileri günlüğe kaydeden bir özellikti .

 @AfterReturning(value = "@annotation(log)", 
       returning = "returnValue", 
       argNames = "joinPoint, log, returnValue"
      )
    public void afterReturning(final JoinPoint joinPoint, final Log log,
            final Object returnValue) {

            Class<?> returnType = ((MethodSignature) joinPoint.getSignature())
            .getReturnType();
           if (Void.class.isAssignableFrom (returnType)) ) {
            //Do some log
         }
}
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.