pxt999 2022-07-03 12:47 采纳率: 0%
浏览 12

Java范型,范型的返回值的接收问题

问题遇到的现象和发生背景

Java范型Iterator<?> iteratorIterator iterator的区别

问题相关代码,请勿粘贴截图

定义一个set

Set<String> set = new HashSet<>();
set.add("aaa")
set.add("bbb")
set.add("bbb")

取它的迭代器

Iterator<String> iterator = set.iterator();
String s = iterator.next();

如果迭代器写成

Iterator<?> iterator = set.iterator();

这句话就会报错

String s = iterator.next();

写成这样才不会报错

String s = (String) iterator.next();

同样这样获得迭代 器:

Iterator iterator = set.iterator();

也只能写成

String s = (String) iterator.next();

而不能写成

String s = iterator.next();

为什么用Iterator<String> iterator获得的迭代器调用next()方法可以返回String,但是Iterator iterator得到的迭代器用next()方法返回的是Object?
还有就是

Iterator<?> iterator = set.iterator();
Iterator iterator = set.iterator();

这两句话有什么区别吗?还是说是完全等价的?

同样定义一个Student

package com.reflect;

public class Student {
    private int age;
    private String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Student() {
    }
}

然后用反射获取Student类的实例,为什么这句话会报错呢?

Class<Student> clazz = Class.forName("com.reflect.Student");

forName()方法定义如下:

public static Class<?> forName(String className) throws ClassNotFoundException {
}

既然这个方法的返回值是Class<?>,不是代表任意的Class范型都可以接收吗?为什么用Class<Student>接收会报错呢?
用下面的方式接收才不会报错,这是为什么

Class<?> clazz = Class.forName("com.reflect.Student");
Class clazz = Class.forName("com.reflect.Student");

Class<?> clazzClass clazz又有什么区别?
并且clazz.newInstance()返回值为什么是一个Object类型,有什么办法让它返回一个Student类型吗?

Object o1 = clazz.newInstance();
Student st = clazz.newInstance(); // 报错

newInstance()定义如下

public T newInstance()
        throws InstantiationException, IllegalAccessException

返回值是T,T在类Class中声明,

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement 

这儿的T为什么会是Object呢?

  • 写回答

1条回答 默认 最新

  • 灯塔@kuaidao 2022-07-03 13:25
    关注

    ? 类型通配符
    T 类型形参

    题主理解的时候也需要结合

    public interface Iterator<E> { .... }
    
    这是一个泛型接口,使用泛型接口需要用泛型实参对泛型形参E进行赋值。(指定一个类型),如果不指定取到的值就是Object。如果使用Iterator<String> 进行赋值。那么接口中所有用到E的地方都用String类型替换。 
    
    评论

报告相同问题?

问题事件

  • 创建了问题 7月3日

悬赏问题

  • ¥20 python忆阻器数字识别
  • ¥15 无法输出helloworld
  • ¥15 高通uboot 打印ubi init err 22
  • ¥20 PDF元数据中的XMP媒体管理属性
  • ¥15 R语言中lasso回归报错
  • ¥15 网站突然不能访问了,上午还好好的
  • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
  • ¥15 semrush,SEO,内嵌网站,api
  • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
  • ¥15 振荡电路,ADS仿真