Day 17
一、反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能
够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射的很灵活和方便,功能非常强大,经常应用于框架和各种技术的底层使用。
public class ReflectDemo01 {
public static void main(String[] args) throws Exception {
//可能需要不同的Person或者子类的对象
Properties pro = new Properties();
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("obj.properties"));
//通过反射的方式创建对象
Person p = (Person) Class.forName(pro.getProperty("name")).newInstance();
p.sleep();
}
}
class Person{
void sleep() {
System.out.println("躺着睡觉...");
}
}
//程序员
class Pro extends Person{
void sleep() {
System.out.println("边敲代码边睡觉...");
}
}
//老师
class Teacher extends Person{
void sleep() {
System.out.println("边讲课边睡觉...");
}
}
//学生
class Student extends Person{
void sleep() {
System.out.println("边听课边睡觉...");
}
}
反射:
java的动态机制
发生在程序运行期间的行为
一个类在加载到内存中,就会存在一个表示当前类的Class类的对象(唯一的,不会变)
Class对象中存在当前这个类的所有内容(属性,构造器,功能…)
创建对象时,其实是拿到Class对象的镜像
如果能够获取到表示一个类的Class对象,就可以进行各种操作…
Class对象是反射的源头
如果能够获取Class对象,就可以使用Class类的中的各种功能来操作
-
如何获取反射的源头:
1.类名.class
2.对象.getClass()
3.Class.forName(“包名.类名”) -->推荐
public class ReflectDemo02 {
public static void main(String[] args) throws Exception {
//1.类名.class
Class cls1 = String.class;
System.out.println(cls1);
//2.对象.getClass()
Class cls2 = "abc".getClass();
System.out.println(cls1 == cls2);
//3.Class.forName("包名.类名") -->推荐
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls3);
//getSuperclass() 获取当前Class对象所表示类型的父类的Class对象
Class cls4 = cls3.getSuperclass();
System.out.println(cls4);
System.out.println(cls4 == Object.class);
//getInterfaces() 获取当前Class对象所表示类型的父接口的Class对象数据
System.out.println(Arrays.toString(cls3.getInterfaces()));
//获取基本数据类型的Class对象 包装类.TYPE
Class cls5 = int.class;
Class cls6 = Integer.class;
System.out.println(cls5);
System.out.println(cls6);
System.out.println(cls5 == cls6);
System.out.println(cls5 == Integer.TYPE);
}
}
-
Java反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理Class类等的使用:
基本的常用的方法
通过获取构造器->反射创建对象
获取方法->调用方法
获取属性–>操作属性
public class ReflectDemo03 {
public static void main(String[] args) {
//getModifiers() 返回Java语言修饰符的类或接口,编码在一个整数。
Class<String> cls = String.class;
System.out.println(cls.getModifiers());
System.out.println(Modifier.toString(cls.getModifiers()));
//String getName()
System.out.println(cls.getName()); //java.lang.String
System.out.println(cls.getSimpleName()); //String
//getPackage() 这个类的包。
System.out.println(cls.getPackage());
//String getTypeName()
System.out.println(cls.getTypeName());
}
}
-
反射获取构造器–>创建对象
Constructor getConstructor(Class<?>… parameterTypes)
获取一个指定的公共额构造器对象Constructor<?>[] getConstructors() 获取所有的公共的构造器对象
Constructor getDeclaredConstructor(Class<?>… parameterTypes)
所有权限的方法中的指定一个
Constructor<?>[] getDeclaredConstructors() 所有的构造器创建对象
1) Class类的newInstance() -->不推荐使用,默认调用空构造,没有就无法使用
2) Constructor类提供的newInstance(Object… initargs)方法创建对象,调用当前的构造器初始化信息public static void testConstructor(Class<User> cls) throws Exception { //获取某个指定的公共的构造器 Constructor<User> con = cls.getConstructor(int.class,String.class,String.class,String.class,Integer.TYPE); System.out.println(con); //所有的构造器 Constructor[] cons = cls.getDeclaredConstructors(); for(Constructor c:cons) { System.out.println(c); } //1.创建对象Class类的newInstance() User obj = cls.newInstance(); System.out.println(obj); //2.Constructor类提供的newInstance(Object... initargs) User obj2 = con.newInstance(1001,"lisi","lisi123","女",18); System.out.println(obj2); //私有的,可以放开权限 cons[1].setAccessible(true); User obj3 = (User) cons[1].newInstance("liaoliao","1234"); cons[1].setAccessible(false); //关闭权限 System.out.println(obj3); } }