[java] 자바에서 변수 캐스팅
누가 캐스팅이 어떻게 작동하는지 말해 줄 수 있을까? 언제 해야하는지 이해 하지만 실제로 어떻게 작동하는지는 이해 하지 못합니다. 원시 데이터 유형에 대해서는 부분적으로 이해하지만 객체를 캐스팅 할 때는 작동 방식을 이해하지 못합니다.
Object 유형의 객체가 갑자기 MyType
(예제 일뿐) 모든 메소드를 얻을 수있는 방법으로 갑자기 캐스트 될 수 있습니까?
답변
Java로 캐스팅하는 것은 마술이 아닙니다. 컴파일러에게 A 유형의 객체가 실제로 더 구체적인 유형 B라는 것을 알려주므로 그렇지 않으면 B의 모든 메소드에 액세스 할 수 있습니다. 캐스팅을 수행 할 때 어떤 종류의 마술이나 변환도 수행하지 않습니다. 기본적으로 컴파일러에게 “저를 믿으세요. 제가하는 일을 알고 있습니다.이 줄에있는이 개체가 실제로 <Insert cast”라는 것을 보장 할 수 있습니다. 여기에 입력>. ” 예를 들면 :
Object o = "str";
String str = (String)o;
위의 내용은 괜찮습니다. 마술이 아닙니다. o에 저장되는 객체는 실제로 문자열이므로 문제없이 문자열로 캐스팅 할 수 있습니다.
이것이 잘못 될 수있는 두 가지 방법이 있습니다. 첫째, 완전히 다른 상속 계층 구조에서 두 유형간에 캐스팅하는 경우 컴파일러는 사용자가 어리 석다는 것을 알고 중지합니다.
String o = "str";
Integer str = (Integer)o; //Compilation fails here
둘째, 동일한 계층 구조에 있지만 여전히 유효하지 않은 캐스트 인 경우 ClassCastException
런타임에 a 가 발생합니다.
Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here
이것은 본질적으로 컴파일러의 신뢰를 위반했음을 의미합니다. 개체가 특정 유형임을 보장 할 수 있다고 말했지만 그렇지 않습니다.
왜 캐스팅이 필요한가요? 글쎄, 시작하려면 더 일반적인 유형에서 더 구체적인 유형으로 이동할 때만 필요합니다. 예, 들어 Integer
로부터 상속 Number
, 그래서 당신이를 저장하려면 Integer
A와 Number
그의 확인 (모든 정수는 숫자이기 때문에.) 그러나, 당신이 캐스트가 필요 둘레에 다른 길을 갈려면 – (모든 숫자가 정수하지뿐만 아니라 우리가 정수로 Double
, Float
, Byte
, Long
, 등) 프로젝트 또는 JDK에서 하나 개의 서브 클래스가있다 그리고 경우에도, 누군가가 쉽게 보장을했습니다 없다, 그래서 당신이 하나의 당연한 선택이라고 생각하더라도, 다른를 작성하고 배포 할 수 !
캐스팅에 대한 사용과 관련하여 일부 라이브러리에서 여전히 필요합니다. Java-5 이전에는 모든 컬렉션이 개체를 추가 한 다음 컬렉션에서 다시 가져온 결과를 캐스팅하기 때문에 컬렉션 및 기타 다양한 클래스에서 많이 사용되었습니다. 그러나 제네릭의 출현으로 캐스팅에 대한 많은 사용이 사라졌습니다. ClassCastExceptions의 가능성없이 훨씬 안전한 대안을 제공하는 제네릭으로 대체되었습니다 (사실 제네릭을 깨끗하게 사용하고 경고없이 컴파일하는 경우, ClassCastException이 발생하지 않을 것이라는 보장이 있습니다.)
답변
실제로 캐스팅이 항상 작동하는 것은 아닙니다. 객체가 instanceof
캐스팅하는 클래스 가 아닌 경우 ClassCastException
런타임에을 얻습니다 .
답변
a String
를 a 로 캐스트하고 싶다고 가정합니다 File
(예, 말이되지 않습니다), File
클래스가 자식이 아니고 클래스의 부모가 아니기 때문에 직접 캐스트 할 수 없습니다 String
(컴파일러가 불평합니다).
그러나 당신은 당신의 캐스팅 수 String
에를 Object
A가 있기 때문에, String
입니다 Object
( Object
부모). 그런 다음 File
파일이 Object
.
따라서 모든 작업은 컴파일 타임에 타이핑 관점에서 ‘합법적’이지만 런타임에 작동한다는 의미는 아닙니다!
File f = (File)(Object) "Stupid cast";
컴파일러는 이해가되지 않더라도이를 허용하지만 다음 예외와 함께 런타임에 충돌이 발생합니다.
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.io.File
답변
참조 캐스팅은 instanceof
해당 유형 인 경우에만 작동합니다 . 무작위 참조를 캐스트 할 수 없습니다. 또한 Casting Objects
.
예 :
String string = "String";
Object object = string; // Perfectly fine since String is an Object
String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.
답변
올바른 방법은 다음과 같습니다.
Integer i = Integer.class.cast(obj);
이 메서드 cast()
는 컴파일 타임 캐스팅보다 훨씬 안전한 대안입니다.