Java反射
什么是反射?使用反射的目的是什么?
反射(reflection),就是程序在运行期不通过访问类的实例,而是通过Class
获取class
类的所有信息,比如类名,包名,有哪些方法,继承等. 目的是为了解决运行期,对某个实例一无所知的情况是,调用其方法。
java 反射的进一步解读:
java中所有的数据类型,除了8中基本类型,其他类型都是class
类;
JVM在加载一个class
时,会自动创建一个Class
的实例,类似这样:
public final class Class{
private Class(){};
}
//比如String类:
Class cls = new Class(String); //JVM先读取String.class到内存,然后创建Class实例并关联起来
所以, JVM中每个Class
实例都指向一个数据类型(class
或者interface
),而这个实例又包含有class的所有信息
如何获取一个class 的实例Class?
- 直接通过class的静态变量class获取:
Class cls = String.class;
- 如果有class的实例变量,则通过该实例变量的getClass()方法获取:
String s = "Hello";
Class cls = s.getClass();
- 如果知道了一个class 的完整类名,则可通过静态方法Class.forName()获取:
Class cls = Class.forName("java.lang.String");
JVM创建的class 的实例Class具有唯一性
注意区分通过这种方法获取的实例与instanceof
的区别:
通过getClass()获取的实例不考虑其子类型,instanceof不仅匹配当前类型,还会匹配子类型:
Integer n = new Integer(8);
Boolean b = n instanceof Integer; // true;
Boolean c = n instanceof Number; //true
Boolean d = n.getClass() == Interger.class; //true
Boolean e = n.getClass() == Number.class; //false
通常使用instanceof
判断数据类型; 只有需要精准判断某个Class 属于某个class时,才会使用==
JVM总是动态加载class,根据条件加载需要的类
Java泛型
1.什么是泛型?泛型的作用是什么?
泛型即参数化类型,类似于方式中定义的形参,在实际方法调用的时候传入实参。
泛型主要应用在集合类中,避免过多的强制类型转换.
2. 泛型有哪些特性?
泛型只在编译阶段有效,泛型信息不会进入到运行阶段。
泛型类型逻辑上看是集中不同的类型,实际上是相同的基本类型。
泛型常常用于各种容器: list set map
//举例说明java泛型
public class ArrayList{
private Object[] array;
private int size;
private add(Object o){};
private remove(int index){};
public Object get(int index){};
ArrayList list = new ArrayList();
list.add("Hello");
String fisrt = (String) list.get(0); //强制类型转换
解决办法是为不同的类型单独编写不同的类: IntegerArrayList, StringArrayList…但是如果遇到很多不同类型的类就会很麻烦,故泛型配上了用场:泛型定义规范或模板, ArrayList <T>
, T 可以为String Integer Float...
可以将ArrayList <T>
想上转型为List<T>
, 但是不能将ArrayList<Integer>
向上转型为ArrayList<Number>
, 这是因为虽然转型了,但是两者还是同一种类型: ArrayList <Integer>
3. 泛型分类:
泛型类 泛型接口 泛型方法
- 泛型类
泛型类的写法:
public class Generic<T>{
class A<E>{
T t;
}
class B <T>{ //类中的方法或类可以再次声明同名泛型,该泛型会覆盖父类的同名泛型T
T t;
}
static class C <T>{
T t;
}
public static void main(String[] args){
T t = null; //报错,不能使用T 泛型,因为泛型属于实例变量,不属于类
}
定义的泛型,非一定要传入泛型类型实参: 如果传入,则会发挥参数限制的作用; 如果没有传入,则泛型中的方法或成员变量的定义类型可以为任意类型
- 泛型接口
public interface Main <T>{
public T next();
}
- 泛型方法
泛型类是在实例化的时候指明泛型的具体类型,泛型方法是在调用时候指明泛型的具体类型
//java泛型方法
public <T> T generator(Class <T> tClass) throws Exception{
T instance = tClass.newInstance();
return instance;
}
Java泛型的实现方式是擦拭法,编译器会将所有类型的<T>
视为Object
处理
泛型的局限性:
<T>
不能为基本类型,因为Object不能持有基本类型- 不能获取带泛型类型的Class
- 不能判断带泛型类型的类型
- 不能实例化
<T>