java反射学习笔记 (一)
反射入门在方法区存在这么一些对象,叫做类对象,他们表述了我们写的所有的类,当我们new对象时会根据这些类对象,并调用其构造方法为我们创建实例。
JAVA反射机制是在运行状态中,对于任意—个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单的说:个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
I
Java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法;生成动态代理
Java反射API
我们所写的每一个类都会被appclassloader加载到内存的方法区,生成一个Class类型的对象,那是你写的Class,也是Class的实例。
Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的Field,Constructor、Annotation类。
注意:Class类是java反射的起源,针对任何一个你想勘测的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。
获取类对象的方法
//创建Person类
public class Person {
private String name;
public Integer age;
public Person(String name) {
this.name = name;
}
public Person(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1、使用类
Class clazz = Person.class;
2、使用全类名 //com.Person
Class aClass = Class.forName("com.Person");
3、使用对象
Person person = new Person();
Class aClass 2 = person.getClass();
//输出结果
class com.empty.Person
class com.empty.Person
class com.empty.Person
对类的操作
//获取类名 类对象:clazz
String name = clazz .getName();
//获取类加载器
ClassLoader classLoader = clazz.getClassLoader();
//获取资源流
URL resource = clazz.getResource("");
clazz.getResourceAsStream("");
//得到父类
Class surperClass = clazz.getSuperClass();
//判断一个类是不是接口/数组等
boolean isArray = clazz.isArray();
boolean isInterface = clazz.isInterface();
//使用Class对象实例化一个对象
Person person= (Person)clazz.newInstance();
//输出结果
com.empty.Person
sun.misc.Launcher$AppClassLoader@18b4aac2
file:/D:/workspace/idea%20workspace/2020-6-4/out/production/2020-6-4/com/empty/
class com.empty.Person
class java.lang.Object
false
false
com.empty.Person@330bedb4
获取字段并操作
//获取字段 获取不了私有属性
Field field = clazz.getField("字段名");
System.out.println(field.getName())
//获取所有公有字段
Field[] fields = clazz.getFields();
for(Field field:fields){
System.out.println(field.getName());
}
//获取私有字段
Field field2 = aClass.getDeclaredField("name");
System.out.println("私有字段:"+field2);
//获取所有字段(包括私有字段)
Field[] declaredFields = aClass.getDeclaredFields();
for(Field field1:declaredFields){
System.out.println(field1.getName());
}
//输出结果
私有字段:name
name
age
//给对象赋值
Person instance = clazz.newInstance(); //实例化Person对象
field2.set(instance,12); //将李明通过set方法复制给instance里面的age。注:只能赋值给公有属性。
System.out.println(field2.getName()+":"+field2.get(instance)); //从实例里取出字段的值,字段:age
//输出结果:
age:18