Bonjour,
ce matin un problème très bête, dans notre beau langage préféré : le java.
Voici ma fonction, somme toute assez conne :
private void addObject(Object tab[],Object nb){
Object tmp[] = new Object[tab.length + 1];
int i = 0;
for (i=0;i<tab.length;i++){
// on recopie le tableau dans le nouveau tableau tmp
System.out.println("tmp["+ i+ "]=tab["+i+"];");
tmp[i]=tab[i];
}
tmp[i]=nb;
tab = tmp; // on retourne l'adresse du tableau tmp
}
J'etais persuadé que seuls les type primitifs etaient recopiés par valeur, mais visiblement dans mon code, le type Object aussi, et il me semble avoir eu des résultats similaire avec String : a la sortie de cette fonction, le tableau tab a toujours la meme adresse, il n'est jamais modifié, alors qu'il devrait normalement avoir l'adresse de tmp non ?
Merci pour votre aide.
# Ca me parrait normal ...
Posté par PiT (site web personnel) . Évalué à 3.
Le passage de paramètre en Java se fait TJS par valeur (même si on passe la valeur de la référence). Ca c'est correct.
Ce que tu n'as pas compris c'est la notion de paramètre formel. Tes deux variables tab et nb sont créées en début de fonction (elles existent pour le bloc) ... et déctruitent à la fin du bloc. Si tu ajoutes un ... println avant ton accolade, tu verras que tab a bien l'adresse de tmp.
Malheureusement, cette variable est détriute à la ligne suivante ... c'est dommage pour toi.
Tu dois retourner cette valeur si tu veux que ça marche ...
NB : J'ai suprimé ta variable nb qui ne sert à rien.
Rem : Ton code n'est pas très lisible (je sais c'est juste pour poser la question) ... tu devrais ajouter des blcs judicieusement placés, faire attention à tes noms de vars ... etc.
[^] # Re: Ca me parrait normal ...
Posté par Pat Le Nain . Évalué à 2.
[^] # Re: Ca me parrait normal ...
Posté par cho7 (site web personnel) . Évalué à 1.
dans le code principal (alias est de type Integer[], code est de type String[]) :
alias = (Integer [])addObject(alias,db.resultset.getInt("Alias"));
code = (String[])addObject(code,db.resultset.getString("Code"));
//Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
dans la fonction on a donc comme vu précédemment :
private Object [] addObject(Object [] tab,Object nb){
Object tmp[] = new Object[tab.length +1];
int i = 0;
for (i=0;i<tab.length;i++){
// on recopie le tableau dans le nouveau tableau tmp
tmp[i]=tab[i];
}
return tmp; // on retourne l'adresse du tableau tmp
}
La solution simple serait de créér une fonction non-générique, mais n'y a t il pas moyen d'en faire une qui le soit ?
[^] # Re: Ca me parrait normal ...
Posté par Pat Le Nain . Évalué à 2.
Dans la fonction, tu crées un tableau de type Object[] (qui peut contenir n'importe quel objet). Ce tableau est ensuite casté vers un tableau de type Integer[].
Le cast ne marche que dans un sens !
Dans le cas des objets, tu peux caster un Integer vers un Object (car Integer hérite de Object). Si tu essayes l'inverse, tu auras droit à un ClassCastException du plus bel effet. Pour les tableaux, c un peu pareil. Tu peux caster un tableau de type Integer[] vers Object[] (car Integer hérite de Object) mais l'inverse n'est pas possible (d'où le ClassCastException).
Correctif - Utilisation de Vector
Un Vector consiste en un tableau d'Object retaillable avec plein de fonctions autour (voir la doc).
Tu replaces tes tableaux par des Vectors. Pour ajouter un objet à la fin du tableau, tu utilises la méthode put(Object valeur). Pour lire un objet à une position donnée tu utilises la méthode get(int index). Jusqu'à Java5, tu est obligé de caster le résultat du get pour obtenir le bon type. Depuis Java5 la généricité permet de s'affranchir dans pas mal de cas du cast.
[^] # Re: Ca me parrait normal ...
Posté par cho7 (site web personnel) . Évalué à 2.
En fait, maintenant comme je suis curieux, je voudrais savoir comment vector fonctionne, car mine de rien, il fait exactement ce que je voulais faire (stocker du int dans un tableau object, il en ajoute autant qu'on veut, puis après il les ressorts a la demande)
Quelqu'un sait ?
[^] # RTFM
Posté par FReEDoM (site web personnel) . Évalué à 2.
si si !
[^] # Re: Ca me parrait normal ...
Posté par Pat Le Nain . Évalué à 2.
[^] # Re: Ca me parrait normal ...
Posté par wismerhill . Évalué à 1.
En particulier, si tu as lu ce code plus question de participer à un projet comme classpath.
[^] # Re: Ca me parrait normal ...
Posté par TImaniac (site web personnel) . Évalué à 3.
Ah que non non pas du tout, en Java5 le compilo met juste les casts à ta place, c'est du joli sucre syntaxique et les casts sont toujours nécessaire, les objets étant toujours stockés sous forme d'Object, ce qui a des graves conséquences en terme de performance lorsqu'on met un type primitif dans un truc générique.
[^] # Re: Ca me parrait normal ...
Posté par Pat Le Nain . Évalué à 2.
les objets étant toujours stockés sous forme d'Object, ce qui a des graves conséquences en terme de performance lorsqu'on met un type primitif dans un truc générique.
Là, tu parles de l'autoboxing (la conversion automatique type-primitif <-> objet), ce qui sort du propos de mon post.
Je persiste à dire que du point de vue du codeur Java (et du source qu'il va pondre), Java5 permet de s'affranchir du cast explicite (vu qu'il le fait implicitement) dans la plupart des cas (il y aura toujours des cas où le cast devra être explicite, genre un objet B héritant de A, un Vector et tu veux utiliser un méthode spécifique de B sur un objet contenu dans le vecteur).
[^] # Re: Ca me parrait normal ...
Posté par TImaniac (site web personnel) . Évalué à 2.
Quoique s'il commence à faire mumuse avec l'introspection...
[^] # Re: Ca me parrait normal ...
Posté par julien . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.