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呢?

? 类型通配符
T 类型形参

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

public interface Iterator<E> { .... }

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