java--反射(一)
一、反射
元数据(MetaData) 描述数据结构的结构;反射就是得到元数据的行为。
二、反射引入
- Object obj = new Student();
若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:
1.若编译和运行类型都知道,使用 instanceof判断后,强转。
2.编译时根本无法预知该对象属于什么类,程序只能依靠运行时信息来发现对象的真实信息,这时就必须使用反射了。
3.要是想得到对象真正的类型,就得使用反射。
三、Class类和Class类实例
- Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class类。
- 对比提问:众多的人用一个什么类表示?众多的Java类用一个什么类表示?
人 Person
Java类 Class
- 对比提问: Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,Class类代表Java类,它的各个实例对象又分别对应什么呢?
- 对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等;
- 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的;
- 一个类在虚拟机中只有一份字节码;
四、获得Class对象
- 如何得到各个字节码对应的实例对象?
- 每个类被加载后,系统会为该类生成对应的Class对象,通过Class对象可以访问到JVM中的这个类,3种方式:
- 使用Class类的forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;
- 调用某个类的class属性获取Class对象,如Date.class会返回Date类对应的Class对象(其实就是得到一个类的一份字节码文件);
- 调用某个对象的getClass()方法。该方法属于Object类;
Class<?> clz = new Date().getClass();
获取对象实例
package reflect;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
enum Gender{
MAN,WOMAN(),NONE{};
}
class User{
}
/**
* 得到Class对象的三种方式:
*
* 1. 通过类的class属性;
* 类.class;
*、 2. 使用Class.forName(String className);className表示 一个类的全限定名
*
* Class clz = Class.forName("java.util.Date");
* 此时 clz 就在描述 java.util.Date这个类
*
* 3. 通过对象的一个 getClass()方法可以搞定
* Class<?> getClass() 返回此 Object 的运行时类。
*
*/
public class ClassDemo {
String name;
public static void main(String[] args) throws Exception {
//得到Usre的字节码
Class<User> clz = User.class;
Class<User> clz2 = reflect.User.class;
System.out.println(clz == clz2);
String className = "java.util.Date";
/**
* public static Class<?> forName(String className)
*
*
* Class<?> clz = Class.forName("java.lang.String");
*/
Class<?> clz3 = Class.forName(className);
Class<Date> clzDate = (Class<Date>) clz3;
System.out.println(clzDate);
System.out.println(clz == Class.forName("reflect.User"));//true
List l = new ArrayList();
Class<?> clzList = l.getClass();
//现在获得l的真实类型
System.out.println(l.getClass());//java.util.ArrayList
//得到对象的真正类型
/**
* enum Gender{
MAN,WOMAN(),NONE{};
}
*/
System.out.println("Gender.MAN= "+Gender.MAN.getClass());//reflect.Gender
System.out.println("Gender.WOMAN= "+Gender.WOMAN.getClass());//reflect.Gender
System.out.println("Gender.NONE= "+Gender.NONE.getClass());//reflect.Gender$1
System.out.println(Map.class);
}
}