로컬 클래스를 사용할 때 "instanceof에 대한 잘못된 제네릭 유형"오류
로컬 클래스 를 사용하는 다음 Java 코드가 있습니다.
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {}
}
}
다음 오류 메시지와 함께 컴파일되지 않습니다.
X.java:8: error: illegal generic type for instanceof
if (o instanceof Z) {}
^
1 error
로컬 클래스 Z
는 X<T>
내부 클래스 인의 제네릭 형식 서명을 상속 한다는 것을 이해합니다 . 이 예제에서는 동일한 종류의 컴파일 오류가 나타납니다. 여기서 Z
is local은 아니지만 여전히 내부에 있습니다.
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compilation error
}
}
Z
비 내부 / 정적 으로 만들어서 해결할 수 있습니다 .
import java.util.Arrays;
public class X<T> {
static class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compiles now
}
}
또는 자격으로X.Z
:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3)) {
if (o instanceof X.Z) {} // Compiles now
if (o instanceof X<?>.Z) {} // Also
}
}
}
그러나 로컬 클래스 자체를 변경하지 않고 로컬 클래스를 한정하거나이 제한을 해결하려면 어떻게해야합니까?
나에게 이것은 Java 언어에 대한 감독 또는 제한으로 보이며 가능하다고 생각하지 않습니다.
The referenced type in an instanceof
expression must be reifiable according to JLS 4.7, meaning that it must be expressed as a reifiable type by its fully qualified name. At the same time, JLS 6.7 states that local classes do not have a fully qualified name, they can therefore not be expressed as reifiable.
If you declare Z as generic, the instanceof
operator treats Z
as a raw type where all generic properties to it - in this case the enclosing class - are considered raw as well. (Similar to a generic methods of a raw type being considered as raw despite any generic signature. This is a measure to retain backwards compatiblity of type generification.) Since any raw type is reifiable, declaring Z to be generic will compile.
A possible workaround is to use reflection:
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
Apparently, by making Z generic compilation succeeds. I expected that to require <T>
as the type parameter, but you just have to make it generic, so anything will do
import java.util.Arrays;
public class X<T> {
void m() {
class Z<Anything> {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
Proper solution would be qualify the local class, but I don't think you can. Either you refactor it to a private static class or that's probably the best you can get.
This should work either. Using reflection too. But seems a valid solution.
import java.util.Arrays;
public class X<T> {
void m() {
class Z2 {
}
for(Object o: Arrays.asList(1,2,3)) {
if(Z2.class.isAssignableFrom(o.getClass())) {
}
}
}
}
'UFO ET IT' 카테고리의 다른 글
"dtrace는 제한된 권한으로 서명 된 실행 파일을 제어 할 수 없습니다"에 대한 해결 방법이 있습니까? (0) | 2020.12.01 |
---|---|
docker run : --rm을 사용하는 이유 (docker newbie) (0) | 2020.12.01 |
F # 대 OCaml : 스택 오버플로 (0) | 2020.12.01 |
Java에서 일반 클래스에 대한 일반 생성자를 만드는 방법은 무엇입니까? (0) | 2020.12.01 |
RuntimeWarning으로 numpy 나누기 : double_scalars에서 잘못된 값이 발견되었습니다. (0) | 2020.12.01 |