source

Java Class.cast() 대 캐스트 연산자

factcode 2022. 9. 6. 22:16
반응형

Java Class.cast() 대 캐스트 연산자

때 의 폐해에 5 C++에서 5의 C++를 알게 기뻤습니다.java.lang.Class을 했다.cast★★★★★★ 。

드디어 캐스팅에 대한 OO의 방법이 생겼다고 생각했습니다.

★★★★★★★★★★★★★★.Class.cast 않다static_castC++라고 하다. 에깝다 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 );
        }
    }
}

이상 저의 질문입니다.

  1. ★★★★★★★★★★ 。Class.cast()네릭릭 츠요시을 사용하다
  2. 를 생성해야 ?Class.cast()컴파일 시에 부정 조건을 판별할 수 있습니까?
  3. 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

반응형