Java의 "ClasscastException"에 대한 설명
-
05-09-2019 - |
문제
"ClasscastException"에 작성된 기사를 읽었지만 좋은 아이디어를 얻을 수 없었습니다. 좋은 기사가 있습니까? 아니면 간단한 설명이 무엇입니까?
해결책
API 사양에서 바로 ClassCastException
:
코드가 인스턴스가 아닌 서브 클래스에 객체를 캐스팅하려고 시도했음을 나타냅니다.
예를 들어, 캐스트를 시도 할 때 Integer
a String
, String
서브 클래스가 아닙니다 Integer
, 그래서 a ClassCastException
던질 것입니다.
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
다른 팁
정말 간단합니다. 클래스 A의 객체를 클래스 B의 객체로 전송하려고하고 호환되지 않으면 클래스 캐스트 예외가 나타납니다.
수업 모음을 생각해 봅시다.
class A {...}
class B extends A {...}
class C extends A {...}
- 모든 Java 클래스가 객체에서 상속되기 때문에 이러한 것들 중 하나를 객체로 캐스팅 할 수 있습니다.
- 둘 다 "종류의"a로 b 또는 c를 A에 캐스트 할 수 있습니다.
- A 개체에 대한 참조를 B에 시전 할 수 있습니다. 경우에만 실제 대상은 B입니다.
- 둘 다 A이더라도 B를 C에 캐스트 할 수 없습니다.
클래스를 다운 캐스트하려는 경우 발생하는 예외이지만 실제로는 수업이 그 유형이 아닙니다.
이 상속장을 고려하십시오.
대상 -> 동물 -> 개
당신은 다음과 같은 메소드가있을 수 있습니다.
public void manipulate(Object o) {
Dog d = (Dog) o;
}
이 코드로 호출 된 경우 :
Animal a = new Animal();
manipulate(a);
그것은 잘 컴파일하지만 런타임에 ClassCastException
O는 실제로 개가 아니라 동물 이었기 때문입니다.
이후 버전의 Java에서는 다음과 같은 경우에 컴파일러 경고를받습니다.
Dog d;
if(o instanceof Dog) {
d = (Dog) o;
} else {
//what you need to do if not
}
예를 고려하십시오.
class Animal {
public void eat(String str) {
System.out.println("Eating for grass");
}
}
class Goat extends Animal {
public void eat(String str) {
System.out.println("blank");
}
}
class Another extends Goat{
public void eat(String str) {
System.out.println("another");
}
}
public class InheritanceSample {
public static void main(String[] args) {
Animal a = new Animal();
Another t5 = (Another) new Goat();
}
}
~에 Another t5 = (Another) new Goat()
: 당신은 얻을 것입니다 ClassCastException
인스턴스를 만들 수 없기 때문입니다 Another
사용 수업 Goat
.
메모: 전환은 수업이 부모 수업을 확장하고 자식 수업이 부모 수업에 시행되는 경우에만 유효합니다.
다루는 방법 ClassCastException
:
- 클래스의 개체를 다른 클래스로 캐스팅하려고 할 때주의하십시오. 새로운 유형이 부모 클래스 중 하나에 속하는지 확인하십시오.
- 제네릭은 컴파일 시간 검사를 제공하고 유형-안전 애플리케이션을 개발하는 데 사용할 수 있기 때문에 제네릭을 사용하여 ClassCastException을 방지 할 수 있습니다.
당신은 대상을 수업의 인스턴스로 취급하려고합니다. 기타에서 댐퍼 페달을 누르는 것과 대략 유사합니다 (피아노에는 댐퍼 페달이 있고 기타는 그렇지 않습니다).
캐스팅의 개념을 이해하십니까? 캐스팅은 유형 변환 과정이며, 정적으로 입력 한 언어이기 때문에 Java로 매우 일반적입니다. 몇 가지 예 :
문자열 "1"을 int-> 문제 없음에 캐스트
문자열 "ABC"를 int->에 캐스트 ClasscastException을 올리십시오.
또는 Animal.class, dog.class 및 cat.class와 함께 클래스 다이어그램을 생각해보십시오.
Animal a = new Dog();
Dog d = (Dog) a; // No problem, the type animal can be casted to a dog, because its a dog.
Cat c = (Dog) a; // Raises class cast exception; you can't cast a dog to a cat.
한 데이터 유형의 객체를 다른 데이터 유형에 캐스팅하려고 할 때 클래스 캐스트 예외는 Java에 의해 던져집니다.
Java를 사용하면 호환 데이터 유형 사이에 주조가 발생하는 한 한 유형의 변수를 다른 유형으로 캐스팅 할 수 있습니다.
예를 들어 문자열을 객체로 캐스트 할 수 있으며 유사하게 문자열 값을 포함하는 객체를 문자열로 시전 할 수 있습니다.
예시
여러 배열리스트 객체를 보유하는 해시 맵이 있다고 가정 해 봅시다.
우리가 다음과 같이 코드를 작성하면 :
String obj = (String) hmp.get(key);
해시 맵의 get 메소드에 의해 반환 된 값은 배열 목록이되기 때문에 클래스 캐스트 예외를 던질 것입니다. 그러나 우리는 그것을 문자열로 캐스팅하려고합니다. 이것은 예외를 일으킬 것입니다.
Java에서 ClasscastException을 위해 줄 수있는 아주 좋은 예는 "Collection"을 사용하는 것입니다.
List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));
for(Object obj:list) {
String str = (String)obj;
}
위의 코드는 런타임에 대한 ClassCastException을 제공합니다. 정수를 문자열로 캐스트하려고하기 때문에 예외가 발생합니다.
JVM이 미지의 것을 추측 할 수 없다는 것을 알게되면 ClassCastException 및 캐스팅을 더 잘 이해할 수 있습니다. B가 A의 인스턴스 인 경우 A는 A보다 더 많은 클래스 멤버와 메소드를 가지고 있습니다. JVM은 매핑 대상이 더 크기 때문에 A에서 B를 캐스팅하는 방법을 추측 할 수 없으며 JVM은 추가 멤버를 채우는 방법을 모릅니다.
그러나 A가 B의 인스턴스 인 경우 A는 B의 전체 인스턴스에 대한 참조이므로 매핑은 일대일이되기 때문에 가능할 것입니다.
Java ClasscastException은 클래스를 한 유형에서 다른 유형으로 부적절하게 변환하려고 할 때 발생할 수있는 예외입니다.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ClassCastExceptionExample {
public ClassCastExceptionExample() {
List list = new ArrayList();
list.add("one");
list.add("two");
Iterator it = list.iterator();
while (it.hasNext()) {
// intentionally throw a ClassCastException by trying to cast a String to an
// Integer (technically this is casting an Object to an Integer, where the Object
// is really a reference to a String:
Integer i = (Integer)it.next();
}
}
public static void main(String[] args) {
new ClassCastExceptionExample();
}
}
이 Java 프로그램을 실행하려고하면 다음 classcastException을 던질 것임을 알 수 있습니다.
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at ClassCastExceptionExample (ClassCastExceptionExample.java:15)
at ClassCastExceptionExample.main (ClassCastExceptionExample.java:19)
예외가 여기에 던져진 이유는 목록 개체를 만들 때 목록에 저장 한 객체가 문자열 "하나"이기 때문입니다. 그러나 나중에이 개체를 제거하려고 할 때 나는 의도적으로 실수를 시도합니다. 정수에 캐스팅하기 위해. 문자열은 정수에 직접 캐스트 할 수 없기 때문에 정수는 문자열의 유형이 아닙니다 - 클래스 캐스트 외환이 던져집니다.
객체를 정렬하고 싶지만 클래스가 비교 가능하거나 비교기를 구현하지 않은 경우 ClassCastException이 나타납니다.
class Animal{
int age;
String type;
public Animal(int age, String type){
this.age = age;
this.type = type;
}
}
public class MainCls{
public static void main(String[] args){
Animal[] arr = {new Animal(2, "Her"), new Animal(3,"Car")};
Arrays.sort(arr);
}
}
위의 주요 방법은 런타임 클래스 캐스트 예외 아래에 던져집니다.
스레드의 예외 "main"java.lang.classcastException : com.default.animal은 java.lang.com에 캐스트 할 수 없습니다.