ClassCastException (Generisches Array)

Freaky123

Mitglied
Also ich muss ein Generisches Array erzeugen und auf dieses dann verschiedene Methoden ausfuehren.
Beim Ausfuehren von der Methode sort in der HelpRing Klasse erhalte ich aber immer nur die ClassCastException weiss vlt jemand wie man das Problem loesen koennte?

Also in der main Methode wird der Ring (INTEGER) erzeugt durch den Konstruktor in der Klasse Ring.
Dann wuerde ich gerne das Array ri.array an die Methode sort in der Klasse HelpRing uebergeben funktioniert leider nicht????

PS: Die Klassen sind nicht volstaendig gepostet...


Java:
public static void main(String[] args) {
		
		Ring<Integer> ri = new Ring<Integer>(10);
		int i = 0;
		
		while (ri.size() < ri.capacity()) {
		       ri.add(i++);
		}
		
		HelpRing.sort(ri.array);

}


public class Ring<T> {

	protected T[] array;
	protected int size;
	protected T current;
	protected int current_pos;
	
	
	@SuppressWarnings("unchecked")
	public Ring(int cap) {
		
		try {
				if (cap<0) throw new IllegalArgumentException();
				else {
					this.array = (T[]) new Object[cap];
					this.size = 0;
					this.current = null;
					this.current_pos = 0;
				}
		} catch (final IllegalArgumentException iae) {
			System.out.println("The capacity can't be negativ, no queue created!");
			}
	}
}


public class HelpRing {

		public static <T extends Comparable<? super T>> void sort(T[] array) {
			
		for (int i=1; i<array.length; i++) {
			for (int j=i; j>0 && (array[j].compareTo(array[j-1])<0); j--) {
				
				T tmp = array[i]; array[i] = array[j]; array[j] = tmp;
			}
		}
		
		
		
		}

}
 
Zuletzt bearbeitet von einem Moderator:
wenn die Generic-Templates am Ende im kompilierten Code weggelassen werden, dann verlangt die Sort-Methode letztlich ein Comparable[],
die Klasse Ring erstellt sich aber ein Object[],

wie wärs wenn du in Ring ein Comparable-Array erstellst und dort den generischen Parameter auch nach Comparable umstellst?
ansonsten hast du in der Tat ein Problem..

denkbar ist dann noch etwas unschön, im Konstuktor von Ring T.class zu übergeben und per Reflection ein richtiges T-Array zu erstellen
 
Also auf Comparable umstellen so vlt:

Java:
public class Ring<T> {
 
    protected Comparable[] array;
    protected int size;
    protected T current;
    protected int current_pos;
    
    
    @SuppressWarnings("unchecked")
    public Ring(int cap) {
        
        try {
                if (cap<0) throw new IllegalArgumentException();
                else {
                    this.array = (Comparable[]) new Object[cap];
                    this.size = 0;
                    this.current = null;
                    this.current_pos = 0;
                }
        } catch (final IllegalArgumentException iae) {
            System.out.println("The capacity can't be negativ, no queue created!");
            }
    }
}
 
ist das eine Frage?
das Array wäre immer noch ein Object[], welches weder hier noch in der sort-Methode auf Comparable gecastet werden kann

der Cast auf T[] ist dagegen was anderes, das ist nur Spass, wird beim Kompilieren wieder rausradiert


ich meinte
this.array = (T[]) new Comparable[cap];
was sich aber mit einem nicht-Comparable-T wohl nicht verträgt, daher auch T als extends Comparable.. deklarieren,
was Ring einschränken würde, Ring geht dann noch auf Integer und alle Comparable, nicht mehr auf alle anderen Klassen,
mag nicht stören
 
Sorry bin noch blutiger Anfaenger in Java, also so ?

Java:
public class Ring<T extends Comparable<? super T>> {

	protected T[] array;
	protected int size;
	protected T current;
	protected int current_pos;
	
	
	@SuppressWarnings("unchecked")
	public Ring(int cap) {
		
		try {
				if (cap<0) throw new IllegalArgumentException();
				else {
					this.array = (T[]) new Comparable[cap];
					this.size = 0;
					this.current = null;
					this.current_pos = 0;
				}
		} catch (final IllegalArgumentException iae) {
			System.out.println("The capacity can't be negativ, no queue created!");
			}
	}
 
so könnte ich mir es vorstellen, falls es nicht zu Fehlern kommt,
das hättest du auch schon testen können und im Falle von Fehlern diese hier posten können 😉
 
Ok getestet hab ich, Fehlermeldungen krieg ich in HelpRing:

Java:
public class HelpRing {

	
	public static <T> void removeAll(Ring<T> ri, T x) {     //Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends Comparable<? super T>> of the type Ring<T>
		
		T tmp = null;
		int i = 0;
		
		while (i<ri.size) {
			tmp = ri.get();
			i++;
			if (tmp.equals(x)) {
				ri.back();
				ri.remove();
			}
		}
	}
	
	
	public static <T> void removeRange(Ring<T> ri, int range) {        //Gleiche Fehlermeldung
		
		try {
			
			if (range>ri.size) throw new IllegalArgumentException();
			
			for (int i=0; i<range; i++) {
				ri.remove();
			}
			
		} catch (IllegalArgumentException iae) { System.out.println("The range is to big"); }
	}
	
	
	
	
	public static <T> void revert(Ring<T> ri) {         //Gleiche Fehlermeldung
		
		int i = ri.size/2;
		int j = 0;
		int k = ri.size-1;
		T tmp = null;
		
		while (j<=i && k>=i) {
			
			tmp = ri.array[j];
			ri.array[j] = ri.array[k];
			ri.array[k] = tmp;
			j++;
			k--;
		}
	}
	
	
	
		
		public static <T extends Comparable<? super T>> void sort(T[] array) {
			
			
		
		for (int i=1; i<array.length; i++) {
			for (int j=i; j>0 && (array[j].compareTo(array[j-1])<0); j--) {
				
				T tmp = array[i]; array[i] = array[j]; array[j] = tmp;
			}
		}
		
		
		
		}

}
 
wie gesagt, einfache Fehler immer gleich testen und dazuposten, dann musst du nicht jeweils 30 Min. oder länger warten 😉

zu diesem Fehler ist meine Ansicht, dass der generische Parameter überall gleich definiert sein muss,
wenn Ring nur für bestimmte T zugelassen ist, dann alle Methoden für Ring genauso einschränken, überall T extends Comparable<? super T>
nicht wirklich schön, ich weiß

wie anfangs erwähnt ist eine Alternative alles bis auf die sort-Methode auf einfaches T zurückzuschrauben,
und als Array
(T[]) Array.newInstance(class, newLength);

wobei class als Parameter im Konstruktor übergeben werden muss,
Aufruf dann z.B.
Ring<Integer> ri = new Ring<Integer>(Integer.class,10);
 
Ok habs jetzt ueberall geaendert nur wirft er mir immer noch die ClassCastException...

Java:
public class HelpRing {

	
	public static <T extends Comparable<? super T>> void removeAll(Ring<T> ri, T x) {
		
		T tmp = null;
		int i = 0;
		
		while (i<ri.size) {
			tmp = ri.get();
			i++;
			if (tmp.equals(x)) {
				ri.back();
				ri.remove();
			}
		}
	}
	
	
	public static <T extends Comparable<? super T>> void removeRange(Ring<T> ri, int range) {
		
		try {
			
			if (range>ri.size) throw new IllegalArgumentException();
			
			for (int i=0; i<range; i++) {
				ri.remove();
			}
			
		} catch (IllegalArgumentException iae) { System.out.println("The range is to big"); }
	}
	
	
	
	
	public static <T extends Comparable<? super T>> void revert(Ring<T> ri) {
		
		int i = ri.size/2;
		int j = 0;
		int k = ri.size-1;
		T tmp = null;
		
		while (j<=i && k>=i) {
			
			tmp = ri.array[j];
			ri.array[j] = ri.array[k];
			ri.array[k] = tmp;
			j++;
			k--;
		}
	}
	
	
	
		
		public static <T extends Comparable<? super T>> void sort(T[] array) {
			
			
		
		for (int i=1; i<array.length; i++) {
			for (int j=i; j>0 && (array[j].compareTo(array[j-1])<0); j--) {
				
				T tmp = array[i]; array[i] = array[j]; array[j] = tmp;
			}
		}
		
		
		
		}

}

Ich glaub die einfachste Loesung waer glaub ich die Sort Methode einfach in die Ring Klasse zu schreiben anstatt in die HelpRing, steht zwar ausdruecklich in der Aufgabenstellung dass sie in HeipRing stehen sollte aber immerhin wuerds dann funktionieren...
 
hmm, Künstlerpech, das Problem war nicht hauptsächlich die sort-Methode, sondern schon in der main der Zugriff auf das Array,
schlechte Position für mich zu meckern, aber hättest du die vollständige Fehlermeldung, etwa

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at test.Test.main(Test.java:14)

gepostet, dann wäre das _früher_ aufgefallen 😉

----

na dafür jetzt zwei laufende Beispiele (enden in NullPointerExceptions, da Inhalte fehlen)

Java:
public class Test {

	public static void main(String arg[]) {
		Ring<Integer> ri = new Ring<Integer>(10);
		int i = 0;

		// while (ri.size() < ri.capacity()) {
		// ri.add(i++);
		// }

		HelpRing.sort(ri.array);

	}
}

class Ring<T extends Comparable<? super T>> {

	protected T[] array;
	protected int size;
	protected T current;
	protected int current_pos;

	@SuppressWarnings("unchecked")
	public Ring(int cap) {

		try {
			if (cap < 0)
				throw new IllegalArgumentException();
			else {
				this.array = (T[]) new Comparable[cap];
				this.size = 0;
				this.current = null;
				this.current_pos = 0;
			}
		} catch (final IllegalArgumentException iae) {
			System.out
					.println("The capacity can't be negativ, no queue created!");
		}
	}
}



class HelpRing {

	public static void sort(Comparable[] array) {

		for (int i = 1; i < array.length; i++) {
			for (int j = i; j > 0 && (array[j].compareTo(array[j - 1]) < 0); j--) {

				Comparable tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
			}
		}

	}

}
Java:
public class Test {

	public static void main(String arg[]) {
		Ring<Integer> ri = new Ring<Integer>(Integer.class, 10);
		int i = 0;

		// while (ri.size() < ri.capacity()) {
		// ri.add(i++);
		// }

		HelpRing.sort(ri.array);

	}
}

class Ring<T> {

	protected T[] array;
	protected int size;
	protected T current;
	protected int current_pos;

	@SuppressWarnings("unchecked")
	public Ring(Class<T> tClass, int cap) {

		try {
			if (cap < 0)
				throw new IllegalArgumentException();
			else {
				this.array = (T[]) Array.newInstance(tClass, cap);
				this.size = 0;
				this.current = null;
				this.current_pos = 0;
			}
		} catch (final IllegalArgumentException iae) {
			System.out
					.println("The capacity can't be negativ, no queue created!");
		}
	}
}

class HelpRing {

	public static <T extends Comparable<? super T>> void sort(T[] array) {

		for (int i = 1; i < array.length; i++) {
			for (int j = i; j > 0 && (array[j].compareTo(array[j - 1]) < 0); j--) {

				T tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
			}
		}

	}

}
 
Wäre es nicht leichter die sort-Methode von Collections zu benutzen? evtl. noch Implementierung an Collections anpassen. sprich statt Array, ArrayList<T> zb...
 

Zurück
Oben