java 学习三
-
反射的基本概念
-
什么是反射?(在程序运行过程中分析类的一种能力)
-
反射能做什么?
-
分析类
-
加载并初始化一个类
-
查看类的所有属性和方法
-
-
查看并使用对象
-
查看一个对象的所有属性和方法
-
-
-
反射的应用场景
-
构造通用的工具
-
搭建具有高度灵活性和扩展性的系统框架
-
-
-
类加载器(ClassLoader)
-
负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象
-
-
Class对象
-
java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件
-
-
类的加载时机
-
创建类的实例
-
Student stu = new Student()
-
-
访问类的静态成员
-
Calendar.getInstance();
-
-
初始化类的子类
-
Class User extends Person{}
-
User user = new User();//先加载父类
-
-
反射方式创建类的class对象
-
Class clazz = Class.forName("类的正名")//正名 :包名+类名 列如:cn.it.demo.Student
-
-
-
-
获取Class对象的三中方式
public class Demo {
//获取Class对象(字节码文件对象)的三种方式
// 1.Object类的getClass()
// Class clazz = 对象名.getClass();
// 2.类的静态属性
// Class clazz = 类名.class;
// 3.Class类的静态方法
// Class clazz = Class.forName("类的正名")
public static void main(String[] args) throws ClassNotFoundException {
//方式一
Student student = new Student();
Class<? extends Student> clazz = student.getClass();
//方法二
Class<Student> clazz1 = Student.class;
//方法三
Class<?> clazz2 = Class.forName("cn.it.pack.Student");
System.out.println(clazz.hashCode());
System.out.println(clazz1.hashCode());
System.out.println(clazz2.hashCode());
}
} -
反射方式获取构造方法并使用
-
Constructor<T> 对象
构造器对象,属于java.base模块,java.lang.reflect包
-
通过Class对象获取构造器对象
-
getConstructor(Class<?>... parameterTypes)
返回一个Constructor对象,仅公共构造函数
Class<?>... :可变参数,代表Class类型的数组
? :通配符,代表不确定的任意类型
-
getDeclaredConstructor(Class<?>... parameterTypes)
返回一个Constructor对象,可获取私有构造函数
-
getConstructors()
返回此类所有(不含私有)构造函数的数组
-
-
Constructor的常用方法
-
String getName()
返回构造函数名
-
T newInstance(Object... initargs)
使用此构造函数和指定参数创建并初始化对象
-
-
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName("cn.it.pack.Student");
//通过反射获取到公共的构造方法(无参)
Constructor cons = clazz.getConstructor();
System.out.println(cons);
//通过反射获取到公共的构造方法(有参)
Constructor cons1 = clazz.getConstructor(String.class);
System.out.println(cons1);
//通过反射获取到私有的构造方法
Constructor cons2 = clazz.getDeclaredConstructor(int.class);
System.out.println(cons2);
//通过反射获取到所有的公共构造方法
Constructor[] constructors = clazz.getConstructors();
for(Constructor c: constructors){
System.out.println(c);
}
//获取到通过反射获取的构造方法名称
System.out.println(cons.getName());
//创建对象实例
Student o = (Student) cons.newInstance();
System.out.println(o);
}
-
反射方式获取成员方法并使用
-
Method对象
方法对象,属于java.base模块,java.lang.reflect包
-
通过Class对象获取方法
-
getMethod(String name ,Class<?>... parameterTypes)
返回一个Method对象,仅公共成员方法
name:方法名
parameterTypes:方法的参数列表
-
getDeclaredMethod(String,Class<?>...)
返回一个Method对象,可获取私有成员方法
-
getMethods()
返回此类所有(不含私有)方法的数组
-
Method的常用方法
-
String getName()
返回方法名
-
Object invoke(Object obj,Object... args)
在指定对象上调用此方法,参数为args
-
-
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("cn.it.pack.Student");
Student o = (Student)clazz.newInstance();
//反射获取到方法 公共方法
Method method1 = clazz.getMethod("say");
System.out.println(method1);
//反射获取到方法 私有方法
Method method2 = clazz.getDeclaredMethod("say1");
System.out.println(method2);
//获取到所有的方法 公共的
Method[] method = clazz.getMethods();
for (Method m : method){
System.out.println(m);
}
//调用此方法
method1.invoke(o);
//开启暴力反射
method2.setAccessible(true);
method2.invoke(o);
}
Field 对象
-
域(属性、成员变量)对象,属于java.base模块,java.lang.reflect包
-
通过Class对象获取属性
-
getField(string name)
返回一个Field对象,仅公共属性
name:属性名
-
getDeclareField(String name)
返回一个Field对象,可获取私有属性
-
getDeclaredFields()
返回此类所有(含私有)属性的数组
-
-
Field的常用方法
-
set(Object obj,Object value)
设置obj对象的指定属性值为value
-
setAccessible(boolean flag)
将此属性的可访问性设置为指定布尔值 (暴力反射) 将private 变成 public
-
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("cn.it.pack.Student");
Student o = (Student)clazz.newInstance();
Field name = clazz.getField("name");
name.set(o, "hxz");
System.out.println("----------------------------------");
Field name1 = clazz.getDeclaredField("age");
name1.setAccessible(true);
name1.set(o,9);
System.out.println(o.toString());
}