8
votes

Est une sous-classe de tableau de chaînes d'un tableau d'objet?

Je pense que je manque quelque chose de base ici. Toute explication ou des pointeurs aux questions précédemment posées sera très utile.

import java.util.Arrays;
import java.util.List;

public class St {

    public static void bla(Object[] gaga) {
            gaga[0] = new Date(); // throws ArrayStoreException
        System.out.println(gaga[0]);
    }

    public static void bla(List<Object> gaga) {
        System.out.println(gaga.get(0));
    }

    public static void main(String[] args) {
            String[] nana = { "bla" };
        bla(nana); // Works fine

        List<String> bla1 = Arrays.asList(args);
        bla(bla1); // Wont compile

            System.out.println(new String[0] instanceof Object[]); // prints true
            System.out.println(nana.getClass().getSuperclass().getSimpleName()); // prints Object
    }

}


0 commentaires

5 Réponses :


11
votes

Les tableaux Java sont Covariant , c'est-à-dire qu'ils autorisent Objet [] FOO = nouvelle chaîne [2]; . Mais cela ne signifie pas qu'ils sont des sous-classes. string [] est une sous-classe de objet (Bien que instanceOf renvoie true, string []. Class.Getsuperclass () retour objet )


3 commentaires

De @maerics commentaire ci-dessous - la nouvelle chaîne de la nouvelle chaîne [0] de l'objet de [0] retourne vrai. Donc, la chaîne [] est un type d'objet et un type d'objet [] et un type de charcutage [], etc. Correct?


@Kal qui semble être un cas particulier pour couvrir la covariance. Voir ma mise à jour


chaîne []> 1 objet semble être un bug, je ne peux pas obtenir getcuperclass pour renvoyer un tableau pour n'importe quel autre type . Mais Java.sun.com/docs/books / jls / tiers_edition / html / ... semble dire que c'est ce qu'il devrait être



3
votes
(new String[0] instanceof Object[]) // => true

0 commentaires

3
votes

Vous êtes correct. Les types de tableau sont covariants en java par design, mais un foo est-pas-a foo . .


0 commentaires

6
votes

Oui, votre hypothèse est valide. Comme indiqué par @bozho, les tableaux sont covariants, alors que les collections génériques (telles que la liste générique) ne sont pas covariantes.

Covariance dans les matrices est risqué: p>

String[] strings = new String[] { "a", "b" }
Object[] objects = strings;
objects[0] = new Date();  // <-- Runtime error here 
String s = strings[0];
s.substring(5, 3);        // ????!! s is not a String 


1 commentaires

Merci .. Je n'ai jamais vu la tremaystoréexception auparavant.



2
votes

chaîne [] est une sous-classe d'objet []

Correct, voir 4.10.3 Sous-tytyping parmi Types de tableau :

Si S et T sont les deux types de référence, alors S []> 1 T [] IFF S> 1 t.

depuis string> 1 objet donc string []> 1 objet []

c'est, ] est un sous-type direct de objet []

objet> 1 objet []

là-bas objet> string [] ; chaîne [] est un (indirect?) sous-type de objet

Aucune relation de ce type n'existe pour les génériques, donc Liste > Liste n'est pas vrai.

maintenant, considérez l'exemple simple suivant: xxx

Il ne compile pas, car x invoque allf avec une liste qui est pas une liste . Pour pouvoir utiliser Liste la signature doit modifier légèrement: xxx

Il compile maintenant. Informellement, li est une liste de certains type qui s'étend / implémente I. SO Liste est < em> attribuable à list . Ce que vous pouvez faire avec une telle liste est limité. Essentiellement, vous pouvez le lire / l'accéder mais ne peut pas écrire / modifier .


2 commentaires

Umm ... Sous-type et sous-classe signifient différentes choses.


@Stephenc, pour les classes sous-tendance est identique à la sous-classement, si je lisez 4.10.2 . Je suppose que la réponse correcte serait "des tableaux ne sont pas des cours afin qu'ils ne puissent pas avoir une relation de sous-classe mais string [] est a sybtype de objet []". Est-ce ce que vous allumez?