#java
#java
Вопрос:
я дергал себя за волосы по ночам, когда получал ClassCastException при попытке преобразовать тип объекта в другой тип объекта…. Я настолько уверен, что этот код будет работать, потому что все объекты являются подклассами класса Object… но каким-то образом я получаю это исключение … кто-нибудь может помочь, ребята?
Извините, ребята .. не путать с оригинальным ArrayList, я изучаю программирование на Java и практикую приведение массивов объектов… исключение находится в строке 8, где я привел массив объектов к типу массива оружия … извините за любую форму троллинга…
public class ArrayList {
public static void main(String args[]){
ArrayList arrayList = new ArrayList();
weapon[] weapons = new weapon[5];
for (int i = 0; i < weapons.length; i ) {
weapons[i] = new weapon(i);
}
weapons = (weapon[]) arrayList.add(weapons,
new weapon(weapons.length 1, "mp5"));
}
public Object[] add(Object[] targetObjectList, Object add){
Object[] oldList = new Object[targetObjectList.length];
for (int i = 0 ; i < oldList.length; i ){
oldList[i] = targetObjectList[i];
}
Object[] newList = new Object[oldList.length 1];
for (int i = 0; i < oldList.length; i ) {
newList[i] = oldList[i];
}
newList[newList.length - 1] = add;
return newList;
}
}//end arrayList class
class weapon {
String name;
int id;
public weapon(int id) {
this.id = id;
name = "weapon";
}
public weapon(int id, String name) {
this.id = id;
this.name = name;
}
}
Комментарии:
1. Ваш код сбил меня с толку оригинальным классом ArrayList в java, я бы счел это действительно плохим стилем именования. P.S. даже методы (.add).
2. Я всего несколько дней на StackOverflow, и кажется, что здесь много троллей.
3. Вы затрудняете ответ на свой вопрос, не сообщая нам, откуда вы получаете исключение, и не публикуя трассировку стека.
4. Что вы пытаетесь сделать с этим кодом. Вы создали массив из 5 видов оружия. После этого вы просто пытаетесь создать 6-е оружие и поместить его в свой массив. Вы могли бы использовать java.util. ArrayList<weaopn> чтобы выполнить это и избавиться от вашего метода add. Вы также могли бы сохранить статический NextID в вашем классе weapon, чтобы он мог генерировать свой собственный идентификатор. Но вы, возможно, захотите объяснить, что вы пытаетесь сделать. В противном случае вы получите очень сложные и слегка неуместные ответы. (не то, чтобы контравариантность была плохой концепцией ..)
5. @Op De Cirkel — вы слышали о Hanlon’s Razor? Смотрите en.wikipedia.org/wiki/Hanlon’s_razor . Хотя, чтобы быть справедливым к OP и другим, подобным ему, проблема обычно не в глупости … но неспособность писать четко и / или непонимание предмета. Если вам трудно с этим справиться, вы, вероятно, зашли не на тот веб-сайт!
Ответ №1:
A weapon
является Object
; следовательно, мы можем рассматривать массив af weapon
как массив Object
. Однако не все Object
s являются weapon
s; следовательно, массив Object
не может обрабатываться как массив weapon
Object
— если только то, что кажется массивом weapon
, на самом деле не было массивом из, чтобы начать с. Из-за этого ваш подход станет затруднительным. Вы могли бы попробовать
weapon[] newList = new weapon[oldList.length 1];
вместо этого, но тогда вам нужно было бы изменить все массивы, чтобы они имели тип weapon[]
, и метод не стал бы общим (что, я полагаю, и является вашей целью). Однако, если вам нужен метод, который может добавлять элемент в любой тип массива, вам следует вместо этого использовать generics.
P.S. Если вы изучаете программирование и массивы, написание такого add()
метода является хорошим упражнением, но если вы «просто хотите, чтобы это работало», вам следует использовать ArrayList
вместо этого, который выполняет всю работу по добавлению за вас.
Комментарии:
1. hmm…my цель состоит в том, чтобы изменить возвращаемый массив объектов на тип оружия array..is возможно ли это сделать без использования ArrayList?
2. @Shizumaru18: Нет, если вы начинаете с
new Object[oldList.length 1]
, потому что тогда вы получаете массив, который знает, что этоObject
массив. Вы можете поместить в него столькоweapon
символов, сколько захотите, но это все равно будетObject
массив. Поскольку этоObject
массив, он фактически позволил бы вам поместить в него что угодно, скажем,Car
или anApple
, и, следовательно, Java не позволит вам обрабатывать его какweapon
массив. Моим советом было бы отказаться от использованияObject
andObject[]
вadd()
и вместо этого использоватьweapon
andweapon[]
.
Ответ №2:
Массивы являются подклассом Object
. Вы не можете привести Object[]
к weapon[]
. Вот общее решение вашей проблемы:
weapons = (weapon[])arrayList.add(weapons, new weapon(weapons.length 1, "mp5"),weapon.class);
и
public <T> T[] add(T[] targetObjectList, T add, Class<T> c) {
T[] oldList = (T[])Array.newInstance(c, targetObjectList.length);
for (int i = 0; i < oldList.length; i ) {
oldList[i] = targetObjectList[i];
}
T[] newList = (T[])Array.newInstance(c, oldList.length 1);
for (int i = 0; i < oldList.length; i ) {
newList[i] = oldList[i];
}
newList[newList.length - 1] = add;
return newList;
}
Примечание: Следуйте Java Naming Conventions
. Избегайте Java API
имен классов в качестве имени вашего класса.
Комментарии:
1. Также System.arraycopy() — ваш друг; приведите к T[].
2. @karamkaze: да. но я только что исправил проблему с приведением.
Ответ №3:
Object o = new Foo()
. Это нормально. Foo — это Object. ПосколькуFoo extends Object
Foo f = new Object()
Не в порядке, объект НЕ Foo (ошибка компилятора)Foo f = (Foo)(new Object())
- ClassCastException
Ответ №4:
То, что вы хотите сделать, известно как контравариантность. Проблема, присущая вашему коду, заключается в том, что МАССИВ, который вы создаете в функции add, представляет собой массив объектов (независимо от того, чем эти объекты в конечном итоге являются).
Если бы вы сделали следующее, ваш код работал бы. Я думаю, что вам нужно работать с обобщениями в этом смысле (посмотрите на фактический класс ArrayList, поскольку он уже реализует это).
...snip...
Object[] newList = new weapon[oldList.length 1];
for (int i = 0; i < oldList.length; i ) {
newList[i] = oldList[i];
}
newList[newList.length - 1] = add;
return newList;
...snip...
Вот пример кода, который работает так, как вы ожидаете.
public class Test {
public static void main(String[] args) {
Integer[] i = (Integer[])Test.get();
}
public static Object[] get() {
Object[] o = new Object[20];
for(int i = 0; i < o.length; i ) {
o[i] = new Integer(0);
}
return o;
}
}
У ArrayList есть метод .toArray(T[] a), который вернет увеличенный размер массива, содержащий ваши новые элементы. Итак, как работает эта контравариантность? Через пакет java.reflect. Это очень маленький отрывок о том, как это на самом деле работает (есть несколько разных пакетов, которые работают вместе, чтобы приступить к этому.)
...Object[] function(Object[] typearray) {
Object[] o = (Object[]) Array.newInstance(typearray.getClass().getComponentType(), 20);
...fill...
return o;
}
Причина, по которой вы должны это сделать, заключается в том, что МАССИВ (поскольку все в Java является объектами) сам является объектом, тогда массив объектов не может быть преобразован в массив целых чисел. Если вы преобразовали массив целых чисел из массива в массив объектов (как показано в приведенном выше примере), а затем снова преобразовали массив объектов в массив целых чисел (поскольку мы никогда не отбрасывали базовый класс, являющийся массивом целых чисел).