Memanggil metode generik statis

106

Saya telah menjumpai situasi aneh yang melibatkan metode generik statis. Ini kodenya:

class Foo<E>
{
    public static <E> Foo<E> createFoo()
    {
        // ...
    }
}

class Bar<E>
{
    private Foo<E> member;

    public Bar()
    {
        member = Foo.createFoo();
    }
}

Kenapa saya tidak harus menentukan argumen tipe apa pun dalam ekspresi Foo.createFoo()? Apakah ini semacam jenis inferensi? Jika saya ingin menjelaskannya secara eksplisit, bagaimana saya dapat menentukan argumen type?

fredoverflow
sumber
7
Saya akan merekomendasikan Anda untuk mengubah parameter tipe E dari metode createFoo. Karena, tipe parameter E kelas Foo berbeda dengan tipe parameter E metode createFoo ().
Gursel Koca
@GurselKoca Dia bisa secara eksplisit melakukan member = Foo. <E> createFoo (); membutuhkan waktu yang sama dengan waktu kompilasi.
George Xavier

Jawaban:

183

Ya, ini adalah jenis inferensi berdasarkan target penugasan, sesuai JLS bagian 15.12.2.8 . Untuk lebih jelasnya, Anda akan menyebut sesuatu seperti:

Foo.<String>createFoo();
Jon Skeet
sumber
3
Atau, seperti dalam kasus saya: Foo.<E>createFoo();Terima kasih :)
fredoverflow
7
Kenapa ini juga berhasil tanpa tugas? Artinya, pernyataan itu Foo.createFoo(); terkompilasi dengan baik ...? Apakah ini karena penghapusan tipe?
fredoverflow
9
@FredOverflow tanpa penugasan E"disimpulkan" menjadiObject
bereputasi
2
Lokasi tautan baru mungkin adalah: docs.oracle.com/javase/specs/jls/se8/html/…
Joanis
3
Cara lain untuk menentukan tipe Eadalah dengan mendefinisikan createFoo()take an argument of type Class<E>(jadi akan demikian createFoo(Class<E> type)), dan menyebutnya dengancreateFoo(String.class)
Gavin S. Yancey