Bagaimana cara melihat apakah suatu objek adalah array tanpa menggunakan refleksi?

99

Bagaimana saya bisa melihat di Java jika Object adalah array tanpa menggunakan refleksi? Dan bagaimana saya bisa mengulang semua item tanpa menggunakan refleksi?

Saya menggunakan Google GWT jadi saya tidak diizinkan menggunakan refleksi :(

Saya ingin menerapkan metode berikut tanpa menggunakan refelection:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

BTW: saya juga tidak ingin menggunakan JavaScript sehingga saya dapat menggunakannya di lingkungan non-GWT.

edbras
sumber

Jawaban:

248

Kamu bisa memakai Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

Ini berfungsi untuk array tipe objek dan primitif.

Untuk toString, lihat Arrays.toString. Anda harus memeriksa jenis array dan memanggil toStringmetode yang sesuai .

Steve Kuo
sumber
1
Layak ditambahkan bahwa Anda dapat mengetahui jenis array dengan menggunakan obj.getClass().getComponentType().
Steve Chambers
68

Anda bisa menggunakan instanceof.

JLS 15.20.2 Operator Pembanding Jenis instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

Pada waktu berjalan, hasil dari instanceofoperator adalah truejika nilai RelationalExpression tidak nulldan referensi dapat dikirim ke ReferenceType tanpa menaikkan a ClassCastException. Jika tidak, hasilnya adalah false.

Artinya, Anda dapat melakukan sesuatu seperti ini:

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

Anda harus memeriksa apakah objek adalah instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], atau Object[], jika Anda ingin mendeteksi semua jenis larik.

Juga, an int[][]adalah an instanceof Object[], jadi tergantung bagaimana Anda ingin menangani array bersarang, ini bisa menjadi rumit.

Untuk toString, java.util.Arraysmemiliki toString(int[])dan kelebihan lainnya yang dapat Anda gunakan. Ini juga memiliki deepToString(Object[])untuk array bersarang.

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

Ini akan menjadi sangat berulang (tetapi bahkan java.util.Arrayssangat berulang ), tapi begitulah di Java dengan array.

Lihat juga

poligenelubricants
sumber
Terima kasih, tidak disadari sesederhana itu. Insstanceof pemikiran tidak dapat digunakan secara langsung dengan T [] :(
edbras
2
BTW: Saya juga melihat cara bagus lainnya untuk mengetahui apakah ada array Class.isArray () (digunakan dalam Arrays.deepToString ()).
edbras
@edbras: ya, itulah yang dikatakan Steve Kuo di bawah. Solusi saya menggunakan konstruksi linguistik murni, bukan panggilan API.
poligenelubricants
Ini berfungsi dengan baik, saya hanya tidak menggunakan instanceof tetapi getClass sebagai perbandingan. Sesuatu seperti: if (array.getClass == int []. Class) {Arrays.toString ((int []) array); } Terima kasih semua ..
edbras
@edbras: Begitulah java.util.Arrays, ya. Saya melihat bahwa Anda telah membaca kode yang saya tautkan.
poligenelubricants
35

Seseorang dapat mengakses setiap elemen array secara terpisah menggunakan kode berikut:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

Perhatikan bahwa tidak perlu untuk mengetahui jenis array yang mendasarinya, karena ini akan berfungsi untuk semua array.

pengguna1928596
sumber
2
isArray()sudah cukup tercakup dalam jawaban yang diposting 4 tahun sebelumnya.
Jason C
15
Jawaban ini bagus karena menunjukkan kepada kita cara mendapatkan ukuran array dan mengambil elemen tanpa mengetahui tipe isinya. Saya yakin kebanyakan orang belum pernah menulis kode seperti ini sebelumnya.
Christopher Yang
@ MaartenBodewes - Saya akan menggunakan tautan ini untuk memutuskan apa arti "tidak menggunakan refleksi" untuk GWT.
Stephen C
10

Tidak ada hubungan subtipe antara array tipe primitif, atau antara array tipe primitif dan array tipe referensi. Lihat JLS 4.10.3 .

Oleh karena itu, berikut ini salah sebagai pengujian untuk melihat apakah objada array jenis apa pun :

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

Secara khusus, itu tidak berfungsi jika objarray 1-D primitif. (Ini berfungsi untuk larik primitif dengan dimensi yang lebih tinggi, karena semua jenis larik adalah subtipe dari Object. Tetapi dalam kasus ini hal ini diperdebatkan.)

Saya menggunakan Google GWT jadi saya tidak diizinkan menggunakan refleksi :(

Solusi terbaik (untuk bagian isArraylarik pertanyaan) bergantung pada apa yang dihitung sebagai "menggunakan refleksi".

  • Di GWT, menelepon obj.getClass().isArray() tidak dihitung menggunakan refleksi 1 , jadi itu adalah solusi terbaik.

  • Jika tidak, cara terbaik untuk mengetahui apakah suatu objek memiliki tipe array adalah dengan menggunakan urutan instanceof ekspresi.

    public boolean isArray(final Object obj) {
        return obj instanceof Object[] || obj instanceof boolean[] ||
           obj instanceof byte[] || obj instanceof short[] ||
           obj instanceof char[] || obj instanceof int[] ||
           obj instanceof long[] || obj instanceof float[] ||
           obj instanceof double[];
    }
  • Anda juga dapat mencoba bermain-main dengan nama kelas objek sebagai berikut, tetapi panggilan ke obj.getClass()berbatasan dengan refleksi.

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }

1 - Lebih tepatnya, Class.isArraymetode ini terdaftar seperti yang didukung oleh GWT di halaman ini .

Stephen C
sumber
0

Anda dapat membuat kelas utilitas untuk memeriksa apakah kelas tersebut mewakili Koleksi , Peta , atau Larik

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }
Lucas Pires
sumber
0

Cukup obj instanceof Object[](diuji di JShell).

Sina Madani
sumber