繁体   English   中英

在 Java 8 中使用.class 进行投射?

[英]Issue casting with .class in Java 8?

我以为.class 是它被调用的 object 的 class 。 然而,这不符合我试图用一个程序做的事情。 我会举一些例子。

//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)

我之前认为sampleClass.class == SampleClass,一个Class类型的object。 我还认为 SampleClass.class 会返回一些真正难以思考的元数据。 现在我知道我真的什么都不知道。 任何帮助解决这个难题表示赞赏:)

编辑:谢谢大家。 我很高兴学习 Java。 我很感激你的帮助

我整理了一些可编译的 Java 代码,这些代码也许可以阐明 Class 和铸造的一些用法。 希望它足够自我记录。

您可以将Sample.class视为“类文字”,就像"something"是字符串文字一样。 它是一个表达式,它有一个值,它可以赋值给一个变量,它是一个 object。 这个 object 的类型Class<Sample> 另一方面, Sample是一种类型,而不是表达式,您不能将其分配给变量。

Class是一个元类,即它是一个 class,它描述了另一个 class。 您不能 go 比Class<Class> classClass = Class.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 { }

}

我之前认为sampleClass.class == SampleClass,一个Class类型的object。

你非常亲近。 正确的理解是sampleClass.getClass() == SampleClass.class , class Class的一个实例。

SampleClass本身是一个类型,而不是一个值。 (在 Java 中,这是一个明确的区别。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM