[英]Issue casting with .class in Java 8?
I thought that.class was the class of the object it was being called on.我以为.class 是它被调用的 object 的 class 。 However this does not fit with what I was trying to do with a program.
然而,这不符合我试图用一个程序做的事情。 I'll give some examples.
我会举一些例子。
//o is of type Object
//this method throws error "cannot find symbol" for the cast method
SampleClass.cast(o);
//sampleClass is an instance of SampleClass
//this method throws error "<identifier> expected"
sampleClass.class.cast(o);
//this method works!
SampleClass.class.cast(o);
//this returns two "<identifier> expected" errors
sampleClass.class.class.cast(o);
//this works too!
((SampleClass) o)
I previously thought that sampleClass.class == SampleClass, an object of type Class.我之前认为sampleClass.class == SampleClass,一个Class类型的object。 I also thought that SampleClass.class would return something really meta that's hard to think about.
我还认为 SampleClass.class 会返回一些真正难以思考的元数据。 Now I know that I don't really know anything.
现在我知道我真的什么都不知道。 Any help solving this conundrum is appreciated:)
任何帮助解决这个难题表示赞赏:)
Edit: Thanks everyone.编辑:谢谢大家。 I'm happy to be learning this about Java.
我很高兴学习 Java。 I'm grateful for the help
我很感激你的帮助
I have put together some compilable Java code that can maybe clarify some usage of Class and casting.我整理了一些可编译的 Java 代码,这些代码也许可以阐明 Class 和铸造的一些用法。 Hopefully it is self-documenting enough.
希望它足够自我记录。
You can think of Sample.class
as a "class literal" in the same way "something"
is a string literal.您可以将
Sample.class
视为“类文字”,就像"something"
是字符串文字一样。 It is an expression, it has a value, it is assignable to a variable, it is an object.它是一个表达式,它有一个值,它可以赋值给一个变量,它是一个 object。 The type of this object is
Class<Sample>
.这个 object 的类型是
Class<Sample>
。 On the other hand Sample
is a type, not an expression, you cannot assign it to a variable.另一方面,
Sample
是一种类型,而不是表达式,您不能将其分配给变量。
Class
is a meta-class, ie it is a class which desribes another class. Class
是一个元类,即它是一个 class,它描述了另一个 class。 You cannot go more meta than Class<Class> classClass = Class.class;
您不能 go 比
Class<Class> classClass = Class.class;
. . Interesting thing: there are also primitive class literals like
int.class
.有趣的事情:还有像
int.class
这样的原始 class 文字。
class Main {
public static void main(String[] args) {
// class literal
Class<Sample> sampleClassLiteral = Sample.class;
final Sample superObject = new Sample();
// dynamic class
// `? extends Sample` because the dynamic type could be a subclass
Class<? extends Sample> superClassMethod = superObject.getClass();
// classes are comparable both by == and equals, because `Class` is final and it does not override the default equals implementation
assert sampleClassLiteral == superClassMethod;
assert sampleClassLiteral.equals(superClassMethod);
Sample subObject = new SubSample();
// dynamic class can be different from the static type of the variable
Class<? extends Sample> subSampleMethod = subObject.getClass();
assert subSampleMethod != superClassMethod;
SubSample staticCast = ((SubSample) subObject);
List<Object> listOfAny = List.of(superObject, subObject, sampleClassLiteral, "some string", 12);
// static type check & casting
final List<Sample> listOfSample = listOfAny.stream()
.filter(elem -> elem instanceof Sample) // Sample.class::isInstance
.map(elem -> (Sample) elem) // Sample.class::cast
.collect(toList());
final List<Sample> samples = listOfTargetClass(listOfAny, Sample.class);
final List<? extends Sample> sameAsSamples = listOfTargetClass(listOfAny, superClassMethod);
// [superObject, subObject] : does NOT contain `sampleClassLiteral` because it's not of type `Sample`, it is of type `Class<Sample>`
System.out.println(samples);
System.out.println(sameAsSamples);
assert samples.equals(sameAsSamples);
final List<SubSample> subSamples = listOfTargetClass(listOfAny, SubSample.class);
System.out.println(subSamples);
}
static <T> List<T> listOfTargetClass(Collection<?> anyCollection, Class<T> targetClass) {
// dynamic type check and casting
return anyCollection.stream()
.filter(targetClass::isInstance) // obj -> targetClass.isInstance(obj)
.map(targetClass::cast) // obj -> targetClass.cast(obj)
.collect(toList());
}
static class Sample { }
static class SubSample extends Sample { }
}
I previously thought that sampleClass.class == SampleClass, an object of type Class.
我之前认为sampleClass.class == SampleClass,一个Class类型的object。
You were very close.你非常亲近。 The correct understanding is that
sampleClass.getClass() == SampleClass.class
, an instance of the class Class
.正确的理解是
sampleClass.getClass() == SampleClass.class
, class Class
的一个实例。
SampleClass
itself is a type, not a value. SampleClass
本身是一个类型,而不是一个值。 (In Java that's a firm distinction.) (在 Java 中,这是一个明确的区别。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.