Gå til innhold

Merkelig kompileringsfeil på generisk klasse


Anbefalte innlegg

Sitter med en oppgave på skolen, programmet er ferdig. Men under kompilering får jeg opp denne feilen;

 

Oblig.java:205:warning: [unchecked] unchecked cast
		private T[] alle = (T[]) new Object[100];
											 ^
required:  T[]
found:  Object[]
where T is a typevariable:
 T extens Object declared in class Beholder
3 warnings

 

Etter å ha lagt til -Xlint bak javac.

Koden ser slik ut;

 

class Beholder<T>{
** Kommentar **
private T[] alle = (T[]) new Object[100];
** En int-variabel og tre helt vanlige metoder for å sette inn/ta ut/returnere antall i arrayet **
}

 

Hva er problemet? Hvordan fikser jeg det?

 

Det eneste jeg foreløpig har funnet ut er å legge til @SuppressWarnings("unchecked") i linja over private T[]... Da kompilerer programmet og kjører helt fint. Men er ikke så begeistra over å måtte omgå problemet for å fikse det.

Lenke til kommentar
Videoannonse
Annonse

Programmet skulle vell kompilere og kjøre fint uansett, det er bare en warning. Ikke en feil.

 

Datastrukturen Array vil aldri bli helt generisk! Men du kan som du sier benytte deg @SuppressWarnings("unchecked") for å fortelle kompilatoren at "dette er greit, ikke noe å bry deg om".

 

Hvis du uansett skal ungå dette for enhver pris og være 100% generisk må du bytte ut Array med feks en ArrayList.

Lenke til kommentar

Er det er feil da?

nei, så - sløvt nok - ikke at det var snakk om generics, i farta. du kan ikke skrive new T[] sånn som jeg foreslo.

 

edit: Skriver du det slik slipper du unna warning.

 

class Beholder<T>{
public static final int INIT_SIZE = 100;

private T[] alle;
public Beholder(T[] alle) {
	// notNull(alle,"alle"); // bruk ditt favorittvalideringsverktøy
	// if (!alle.length == INIT_SIZE) throw new RuntimeException;
	this.alle = alle;
}
public void setAlle(T[] alle) {
	this.alle = alle;
}
public static void main(String[] args) {
	Beholder<String> b = new Beholder<String>(new String[] {"en","to","tre"});
	Beholder<Integer> i = new Beholder<Integer>(new Integer[beholder.INIT_SIZE]);
}
}

 

Du må som du ser "delegere ut" initiell array-size, men det er vel å anse som straffen for ikke å bruke collections ...

Endret av quantum
Lenke til kommentar

Feilen er egentlig ganske forståelig.

 

Grunnen til at den klager her, er at du forsøker en unchecked casting fra object[] til int[].

 

Sett at du gjør slik:

Object[] original = new Object[100];
Integer[] ints = (Integer[])original;
original[0] = 1.0;
int v = ints[0];

I dette tilflellet ville original[0] være en double, men ints hadde hevdet at alle elementene er integer. Det er rett og slett en brudd på trygg typesetting å caste et object[] til et int[] eller andre typer.

Lenke til kommentar

Grunnen til at den klager her, er at du forsøker en unchecked casting fra object[] til int[].

 

 

Oppgaven her er litt skrudd, spør du meg, det er vel kanskje et pedagogisk poeng med det ... antar du har et tilsvarende point med å grise ytterligere ved å blande inn primitive typer :) Koden din kompilerer jo uten warnings, men smeller runtime.

 

Og det gjør det jo også om man ikke blander inn primitive typer:

 


class Beholder<T>{
public T[] alle2 = (T[]) new Object[100];
public Beholder() {
	alle2[0] = (T) new Long(Integer.MAX_VALUE +1);
}
public static void main(String[] argz) {
	Beholder<Integer> b = new Beholder<Integer>();
	//System.out.println(b.alle2.length);
}
}

 

Eksempelet over går faktisk fint, så lenge man ikke snakker mer om variablen alle2 (eller evt. andre variable som befinner seg i kassen), men det har nok mest med optimalisering å gjøre ...

Endret av quantum
Lenke til kommentar

Vil tippe at det pedagogiske poenget er at vi skal lage en generisk klasse, på grunn av at vi skal lage det igjen senere. But I dunno really. Koden til beholder-klassen står det i obligtekst at vi kan ta fra et notat skrevet av han ene foreleseren.

 

For å sjekke at jeg har forstått det rett; problemet er at jeg ikke spesifiserer i Beholderklassen hva slags objekt den skal oppbevare, noe kompilatoren ikke liker?

 

Så to enkle løsninger er å;

1: Lage en konstruktør i Beholder-klassen og delegere opprettelsen av array-type og størrelse dit.

eller

2: Bruke ArrayList istedenfor vanlig array.

Om jeg forstår det rett?

 

Ninjaedit; Valideringsverktøy..? Tenker på f.eks. if(alle == null)?

 

Delegerte ansvaret for opprettelsen av arrayet til konstruktør(og så en annen klasse), og den kompilerer uten problem! Tusen takk for hjelpen, da kan jeg ihvertfall levere den med god samvittighet :)

Endret av sleggefett
Lenke til kommentar

Ganske vanlig at man ser studenter bruker arrays. I praksis vil jeg påstå at det sjelden er et godt valg. Jeg vet ikke helt hvorfor det er sånn, enten er det et pedagogisk poeng som foreleserne prøver å få frem eller så sitter de litt for godt fast i akademia uten praktisk erfaring. Det er bedre å bruke collections-typer som f.eks. implementasjoner av List.

Lenke til kommentar

 

2: Bruke ArrayList istedenfor vanlig array.

 

Ja, det er jo det mest opplagte. Det blir litt uggent når man blander generics og Array, noe dette kodeeksempelet viser. Sånn sett er det jo et Kinderegg av en oppgave, tre poeng på en gang! Hvordan kode generics, hvordan kode array og hvordan ikke blande de to tingene :o)

 

Hvis du tar en titt på kildekoden til ArrayList f.eks., så ser du at implementasjonen bruker array internt og må caste og annotere unchecked på samme måte. Men det er vel litt av hensikten med collections-rammeverket, å skjule griseriet så vi slipper å forholde oss til det i det daglige.

Lenke til kommentar

Ganske vanlig at man ser studenter bruker arrays.

De skal nå engang lære å implementere datastrukturer som stack, heap, linkedlist og så videre. Selv om det i praksis ofte er bedre å benytte seg av rammeverk som Java Collections. For det bør man jo _også_ ha lært.

Lenke til kommentar

De skal nå engang lære å implementere datastrukturer som stack, heap, linkedlist og så videre. Selv om det i praksis ofte er bedre å benytte seg av rammeverk som Java Collections. For det bør man jo _også_ ha lært.

 

Ja, jeg var litt uklar. Jeg mente egentlig studenter som kommer inn i arbeidslivet. De har ofte ikke lært f.eks. Java Collections særlig godt. De som kan det har lest seg opp på egenhånd. Nå er det tross alt ikke et Java-studie de fleste tar så det er vel kanskje vanskelig å unngå at det blir sånn. Selvsagt er det viktig at man lærer de underliggende mekanismene også.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...