Java Class.cast() 대 캐스트 연산자
때 의 폐해에 5 C++에서 5의 C++를 알게 기뻤습니다.java.lang.Class
을 했다.cast
★★★★★★ 。
드디어 캐스팅에 대한 OO의 방법이 생겼다고 생각했습니다.
★★★★★★★★★★★★★★.Class.cast
않다static_cast
C++라고 하다. 에깝다 like에 가깝습니다.reinterpret_cast
. 런타임에 컴파일 오류는 예상된 곳에서 발생하지 않고 런타임에 따라 처리됩니다.다음은 다양한 동작을 보여주는 간단한 테스트 사례입니다.
package test;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class TestCast
{
static final class Foo
{
}
static class Bar
{
}
static final class BarSubclass
extends Bar
{
}
@Test
public void test ( )
{
final Foo foo = new Foo( );
final Bar bar = new Bar( );
final BarSubclass bar_subclass = new BarSubclass( );
{
final Bar bar_ref = bar;
}
{
// Compilation error
final Bar bar_ref = foo;
}
{
// Compilation error
final Bar bar_ref = (Bar) foo;
}
try
{
// !!! Compiles fine, runtime exception
Bar.class.cast( foo );
}
catch ( final ClassCastException ex )
{
assertTrue( true );
}
{
final Bar bar_ref = bar_subclass;
}
try
{
// Compiles fine, runtime exception, equivalent of C++ dynamic_cast
final BarSubclass bar_subclass_ref = (BarSubclass) bar;
}
catch ( final ClassCastException ex )
{
assertTrue( true );
}
}
}
이상 저의 질문입니다.
- ★★★★★★★★★★ 。
Class.cast()
네릭릭 츠요시을 사용하다 - 를 생성해야 ?
Class.cast()
컴파일 시에 부정 조건을 판별할 수 있습니까? - Java는 C++와 유사한 언어 구조로 캐스트 연산자를 제공해야 합니까?
는 지금까지 ★★★★★★★★★★★★★★★★★★★★★★★★★만.Class.cast(Object)
'이렇게 하다'이치하다
@SuppressWarnings("unchecked")
<T> T doSomething() {
Object o;
// snip
return (T) o;
}
대부분의 경우 다음과 같은 방법으로 교체하는 것이 좋습니다.
<T> T doSomething(Class<T> cls) {
Object o;
// snip
return cls.cast(o);
}
라고 할 수 있습니다.Class.cast(Object)
나는 마주친 적이 있다.
내 엔 그렇겠지?Class.cast(Object)
컴파일러에게 특별한 것은 아닙니다.사용하는 정적으로 사용하는 경우) 될 수 .Foo.class.cast(o)
cls.cast(o)
하지만, 그것을 사용하고 있는 사람은 본 적이 없습니다.이 때문에, 컴파일러에 최적화를 짜넣는 노력은 다소 가치가 없습니다.
첫째, 거의 모든 캐스팅을 하는 것을 강하게 권장하지 않기 때문에 가능한 한 제한해야 합니다!Java의 컴파일 시간 강력한 유형의 기능이 제공하는 이점을 잃게 됩니다.
경우든, 「」입니다.Class.cast()
' 때'를 사용하세요.Class
반사에 의한 토큰. 쓰는 것이 더
MyObject myObject = (MyObject) object
보다는
MyObject myObject = MyObject.class.cast(object)
편집: 컴파일 시 오류 발생
전체적으로 Java는 런타임에만 캐스트 체크를 수행합니다.그러나 컴파일러는 이러한 캐스트가 결코 성공할 수 없음을 증명할 수 있다면 오류를 발생시킬 수 있습니다(예를 들어 슈퍼타입이 아닌 다른 클래스에 클래스를 캐스팅하고 타입 계층에 없는 클래스/인터페이스에 최종 클래스 유형을 캐스팅합니다).★★★★★★★★★★★★★★ Foo
★★★★★★★★★★★★★★★★★」Bar
서로 다른 계층에 속하지 않는 클래스이기 때문에 캐스팅은 성공할 수 없습니다.
언어간에 구문이나 개념을 번역하려고 하는 것은 항상 문제가 있고 종종 오해의 소지가 있습니다.캐스팅도 예외는 아니다.특히 자바는 동적 언어이고 C++는 다소 다르기 때문입니다.
자바에서의 모든 캐스팅은 어떻게 하든 런타임에 이루어집니다.유형 정보는 런타임에 유지됩니다.C++는 조금 더 혼합되어 있습니다.C++의 구조를 다른 구조체에 캐스팅할 수 있으며 이러한 구조를 나타내는 바이트의 재해석일 뿐입니다.Java는 그런 식으로 작동하지 않습니다.
Java와 C++의 제네릭도 크게 다릅니다.Java에서 C++ 작업을 수행하는 방법에 대해 지나치게 신경 쓰지 마십시오.자바 방식으로 일을 처리하는 방법을 배워야 합니다.
Class.cast()
Java ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」시에만 의 유형을 )에 됩니다.Class
브젝트및및및및및유유유유유유유유유유)Generic을 사용하는 코드에서만 매우 유용합니다(그것이 바로 이전에 도입되지 않은 이유이기도 합니다.
와는 다르다.reinterpret_cast
실행 시 일반 캐스트와 마찬가지로 타입 시스템을 절단할 수 없기 때문입니다(즉, 범용 타입 파라미터는 해제할 수 있지만 "실제" 타입은 해제할 수 없습니다).
C스타일의 캐스트 오퍼레이터의 폐해는 일반적으로 자바에는 적용되지 않습니다.는 C스타일의 Java 코드와 합니다.dynamic_cast<>()
(자바)
일반적으로 C++ 캐스팅 연산자와 Java 캐스팅을 비교하는 것은 매우 어렵습니다. Java에서는 참조만 캐스팅할 수 있고 오브젝트에 대한 변환은 발생하지 않습니다(이 구문을 사용하여 원시 값만 변환할 수 있습니다).
일반적으로 cast 연산자는 Class #cast 메서드보다 더 간결하고 컴파일러에 의해 분석되어 코드의 명백한 문제를 뱉을 수 있기 때문에 선호됩니다.
class #cast는 컴파일 중이 아니라 런타임에 유형 체크를 담당합니다.
Class #cast에는 특히 리플렉티브 오퍼레이션에 관한 유스케이스가 있습니다.
lamda가 java로 넘어왔기 때문에 저는 개인적으로 추상적인 타입으로 작업하는 경우 컬렉션/스트림 API와 함께 Class #cast를 사용하는 것을 좋아합니다.
Dog findMyDog(String name, Breed breed) {
return lostAnimals.stream()
.filter(Dog.class::isInstance)
.map(Dog.class::cast)
.filter(dog -> dog.getName().equalsIgnoreCase(name))
.filter(dog -> dog.getBreed() == breed)
.findFirst()
.orElse(null);
}
C++와 Java는 다른 언어입니다.
Java C 스타일 캐스트 연산자는 C/C++ 버전보다 훨씬 더 제한적입니다.실제로 Java 캐스트는 C++ dynamic_cast와 같습니다.사용자가 가지고 있는 오브젝트를 새로운 클래스에 캐스트 할 수 없는 경우 실행 시간(또는 컴파일 시간 코드에 충분한 정보가 있는 경우) 예외가 발생합니다.따라서 C타입 캐스트를 사용하지 않는다는 C++ 생각은 Java에서 좋은 생각이 아닙니다.
Class.cast는 가장 많이 언급한 추악한 캐스트 경고를 삭제할 뿐만 아니라 범용 캐스트와 함께 주로 사용되는 런타임 캐스트입니다.이는 실행 시 일반 정보가 지워지고 각 범용이 오브젝트로 간주되는 방식이 일부 있기 때문에 초기 ClassCast Exception이 느려지지 않기 때문입니다.
예를 들어 serviceLoder는 개체를 만들 때 이 트릭을 사용합니다. S p = service.cast(c.newInstance()). 그러면 S P =(S) c.newInstance()가 생성되지 않을 때 클래스 캐스트 예외가 발생하며 'Type safety: 개체에서 S'로의 캐스트 체크가 해제되었습니다(개체 P =(개체) c.newInstance();).
-casted 객체가 캐스팅 클래스의 인스턴스인지 확인한 후 캐스트 연산자를 사용하여 경고를 캐스트하고 숨깁니다.
동적 캐스트를 위한 Java 구현:
@SuppressWarnings("unchecked")
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
}
private S nextService() {
if (!hasNextService())
throw new NoSuchElementException();
String cn = nextName;
nextName = null;
Class<?> c = null;
try {
c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
}
if (!service.isAssignableFrom(c)) {
fail(service,
"Provider " + cn + " not a subtype");
}
try {
S p = service.cast(c.newInstance());
providers.put(cn, p);
return p;
} catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated",
x);
}
throw new Error(); // This cannot happen
}
JSON-POJO의 약자 또는 JSONObject가 경우( JSONObject가 ).String
)를 사용하여 class.cast()
다음과 같이 합니다.
public static Object convertResponse(Class<?> clazz, JSONObject readResultObject) {
...
for(Method m : clazz.getMethods()) {
if(!m.isAnnotationPresent(convertResultIgnore.class) &&
m.getName().toLowerCase().startsWith("set")) {
...
m.invoke(returnObject, m.getParameters()[0].getClass().cast(convertResponse(m.getParameters()[0].getType(), readResultObject.getJSONObject(key))));
}
...
}
이 큰 바와 몇 안 되는 중 입니다.class.cast()
적어도 이제 다른 예가 생겼을 거라고 생각할 수 있어요.
언급URL : https://stackoverflow.com/questions/1555326/java-class-cast-vs-cast-operator
'source' 카테고리의 다른 글
파일 권한을 프로그래밍 방식으로 변경하려면 어떻게 해야 합니까? (0) | 2022.09.06 |
---|---|
이상한 세그먼트화(코어 덤프화) - C 프로그래밍 언어 연습 13 (0) | 2022.09.06 |
다국어 정규 표현 단위 테스트는 어디서 볼 수 있나요? (0) | 2022.09.06 |
포인터로 가리키는 int의 증분값 (0) | 2022.09.06 |
지정된 클래스의 모든 하위 클래스를 찾으려면 어떻게 해야 합니까? (0) | 2022.09.06 |