反射:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
通过类的加载,自审(省),探知在编译期间未知的类对象的类型信息。
如何获取类的类型信息(Class对象)?(4种方法)
1.如果已经条件是一个对象(obj)
Class<?> clazz = obj.getClass();
2.如果已经条件是类名
Class<?> clazz = 类.class;
Class<?> clazz = Class.forName("包名.类名");
3.对于基本类型包装类(int->Integer)
Class<?> clazz = Integer.Type;
有了类的类型对象,可以探知类的内结构(构造器,父类,属性,方法,...)?
获取构造器的4种方法?
//返回指定参数的构造器
Constructor cons = clazz.getDeclaredConStructor([参数类型]);
//返回指定参数的公共构造器
Constructor cons = clazz.getConStructor([参数类型]);
//返回所有构造器的一个数组
Constructor[] cons = clazz.getDeclaredConStructors();
//返回所有公共构造器的一个数组
Constructor[] cons = clazz.getConStructors();
获取属性对象的4种方法?
//返回指定属性名的属性对象
Field field = clazz.getDeclaredField("属性名");
//返回指定公共属性名的属性对象
Field field = clazz.getField("属性名");
//返回指定属性名的属性对象的一个数组
Field[] fields = clazz.getDeclaredFields();
//返回指定公共属性名的属性对象的一个数组
Field[] fields = clazz.getFields();
获取方法对象的4种方法?
//返回指定方法名的方法对象
Method method = clazz.getDeclaredMethod("方法名");
//返回指定方法名的公共方法对象
Method method = clazz.getMethod("方法名");
//返回所有方法对象的数组
Method[] methods = clazz.getDeclaredMethods();
//返回所有公共方法对象的数组
Method[] methods = clazz.getMethods();
使用类型对象实例化对象(类中必须包含无参构造)?
Object obj = clazz.newInstance();
Class<T>:
表示T类的类型
newInstance()
创建此Class对象所表示的类的一个新实例。如同用一个带有一个空参数列表的 new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。
String s = new String();
等同于上面的代码
Class<?> c = String.class;//c引用String类的类型对象
String s = c.newInstance();
Constructor<?>[] getConstructors():
获取类的所有公共构造器数组
Field[] getFields()
返回一个包含某些类的属性的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段
Method[] getMethods()
返回一个包含某些类的属性的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
如果根据参数类型,获取构造器
Contructor getDeclareContructor(参数类型...)
如果根据参数类型,获取公共构造器
Contructor getContructor(参数类型...)
所有构造器数组
Contructor[] getDeclareContructors()
所有公共构造器数组
Contructor[] getContructors()
方式一:
Product p = new Product();
Class<?> clazz = p.getClass();
方式二:
Class<?> c = Class.forName("class类名(全路径)");
方式三:
Class<?> c = Product.class;
package cn.itcast_01;
/*
* 反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
*
* Person p = new Person();
* p.使用
*
* 要想这样使用,首先你必须得到class文件对象,其实也就是得到Class类的对象。
* Class类:
* 成员变量 Field
* 构造方法 Constructor
* 成员方法 Method
*
* 获取class文件对象的方式:
* A:Object类的getClass()方法
* B:数据类型的静态属性class
* C:Class类中的静态方法
* public static Class forName(String className)
*
* 一般我们到底使用谁呢?
* A:自己玩 任选一种,第二种比较方便
* B:开发 第三种
* 为什么呢?因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 方式1
Person p = new Person();
Class c = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p == p2);// false
System.out.println(c == c2);// true
// 方式2
Class c3 = Person.class;
// int.class;
// String.class;
System.out.println(c == c3);
// 方式3
// ClassNotFoundException
Class c4 = Class.forName("cn.itcast_01.Person");
System.out.println(c == c4);
}
}