类加载器
类加载
类加载器
反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射就是把java类中的各种成分映射成一个个的Java对象
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时怕判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
生成动态代C理
Class类
- Class本身也是一个类
- Class对象只能由系统建立对象
- 一个类在JVM中只会有一个class实例
- 一个Class对象对应的是一个加载到JVM中的一个.class文件
- 每个类的实例都会记得自己是由那个Class实例所生成
- 通过Class可以完整的得到一个类中的完整结构
通过反射获取一个类的父类和接口
Class clazz = Class.forName("day14.Student")
//通过包.类名的字符串,调用class.forName方法获取指定类的Class实例
Class superClazz = clazz.getSuperclass();//获取父类
sout(superClazz .getName())//输出父类名字
Class[] interfaces = clazz.getInterfaces();//获取当前类的所有接口
for(Class c : interfaces){
sout(c.getName())//输出接口名字
}
通过反射获取一个类的构造方法
加入三个构造方法
getConstructors 获取类的公有的构造方法
getModifiers获取构造方法的修饰符,返回数组1代表public
getParameterTypes获取构造方法的参数类型,有几个参数数组的元素就有几个
import java.lang.reflect.Constructor;
Constructor[] cons = clazz.getConstructors();//获取当前类的所有构造方法
for(Constructor c : cons){
sout(c.getName());//输出构造方法名字
sout(c.getModifiers());//输出构造方法修饰符
Class[] paramClazz = c.getParameterTypes();
for(Class pc : paramClazz){
sout(pc.getName());//输出构造方法的参数类型
}
}
getDeclaredConstructors获取类的所有的构造方法,包括公有和私有
getModifiers获取方法的修饰符,返回数组2代表private
Constructor[] cons1 = clazz.getDeclaredConstructors();//获取当前类的所有接口
for(Constructor c : cons1){
sout(c.getName());//输出构造方法名字
sout(c.getModifiers());//输出构造方法修饰符
}
通过反射创建一个对象
都是class类型的参参数。
//相当于调用Student类的无参公有的构造方法
Object obj = clazz.newInstance();
Student stu = (Student)obj;//obj强转为Student对象
//相当于调用Student类的有一个参数并且为String类型的公有的构造方法
Constructor c= clazz.getConstructor(String.class);
Object obj = c.newInstance("第一中学");//通过newInstance实例化对象,相当于调用构造方法
Student stu = (Student)obj;//obj强转为Student对象
通过反射机制,可以强制调用私有的构造方法
//相当于调用Student类的有两个个参数并且为String类型和int类型的的构造方法
Constructor c= clazz.getConstructor(String.class,int.class);
c.setAccessible(true);//解除私有的封装,下面就可以对这个私有方法进行强制调用
Object obj = c.newInstance("张三",12);//通过newInstance实例化对象,相当于调用构造方法
Student stu = (Student)obj;//obj强转为Student对象
通过反射获取类的方法
获取所有类的公有的方法
//获取所有类的公有的方法
Method[] ms= clazz.getMethods();
for(Method m : ms){
sout(m.getName());//输出方法名字
sout(m.getReturnType());//输出方法返回类型
sout(m.getModifiers());//输出方法修饰符
//获取方法的参数类型,是一个数组,方法有几个参数,数组就有几个元素
Class[] pcs = m.getParameterTypes();
if(pcs!=null&&pcs.length>0){
for(Class pc : pcs){
sout(pc.getName());//输出方法的参数类型
}
}
}
获取所有类的所有方法,包含公有私有
//获取所有类的公有的方法,包含公有私有
Method[] ms= clazz.getDeclaredMethods();
for(Method m : ms){
sout(m.getName());//输出方法名字
sout(m.getReturnType());//输出方法返回类型
sout(m.getModifiers());//输出方法修饰符
//获取方法的参数类型,是一个数组,方法有几个参数,数组就有几个元素
Class[] pcs = m.getParameterTypes();
if(pcs!=null&&pcs.length>0){
for(Class pc : pcs){
sout(pc.getName());//输出方法的参数类型
}
}
}
通过反射获取类的方法属性和包
获取类的公有的属性,包含父类的公有属性
//获取类的公有的属性,包含父类的公有属性
Field[] fs= clazz.getFields();
for(Field f : fs){
sout(m.getModifiers());//输出属性修饰符
sout(m.getType());//输出属性的类型
sout(m.getName());//输出属性名称
}
获取本类(不包含父类)的公有的属性,包括公有、私有
//获取本类(不包含父类)的所有的属性,包括公有、私有
Field[] fs= clazz.getDeclaredFields();
for(Field f : fs){
sout(m.getModifiers());//输出属性修饰符
sout(m.getType());//输出属性的类型
sout(m.getName());//输出属性名称
}
获取类所在的包
//获取类所在的包
Package p = clazz.getPackage();
sout(p.getName());//输出包的名称
通过反射获取类的指定方法和指定属性
调用公有方法
//获取类的指定方法
Constructor c= clazz.getConstructor();//获取无参构造
Object obj = con.newInstance();//使用无参构造创建对象
clazz.getMethod(方法名,参数类型);
Method m = clazz.getMethod("setInfo",String.class,String.class);//得到名称叫setInfo,参数是String,String的类型的方法
m.invoke(obj(需要实例化的对象),args(调用当前方法的实际参数))
m.invoke(obj,"zhangsan","第一中学")
调用私有有参数方法
//获取类的指定方法
Constructor c= clazz.getConstructor();//获取无参构造
Object obj = con.newInstance();//使用无参构造创建对象
clazz.getDeclaredMethod(方法名,参数类型);
Method m1 = clazz.getDeclaredMethod("test",String.class);//得到名称叫test,参数是一个String的类型的方法
m1.setAccessible(true);//解除私有封装,下面可以强制调用私有方法
m1.invoke(obj(需要实例化的对象),args(调用当前方法的实际参数))
m1.invoke(obj,"李四")
不论是反射调用的公有方法和私有方法,都是调用的创建对象obj的方法,obj对象时间上就是student方法
调用重载方法
重载setInfo方法
//获取类的指定方法
Constructor c= clazz.getConstructor();//获取无参构造
Object obj = con.newInstance();//使用无参构造创建对象
Method m2 = clazz.getMethod("setInfo",int.class);//得到setInfo的重载方法
m2.invoke(obj(需要实例化的对象),args(调用当前方法的实际参数))
m2.invoke(obj,1)
调用有返回值但没有参数的方法
Method m3 = clazz.getMethod("getSchool");//得到方法名为getSchool,并且没有参数的方法
String school = (String)m3.invoke(obj);//Object类强转为String类
sout(school);
调用指定属性
输出公有的属性
//反射创建一个对象
Constructor c= clazz.getConstructor();//获取无参构造
Student stu = (Student)con.newInstance();//使用无参构造创建对象
//访问属性
Field f = clazz.getField("school");//得到名称为school的属性
f.set(stu,"第三中学");//对stu对象的school属性设置值第三中学
String school = (String)f.set(stu,"第三中学");//获取stu对象的school属性的值
sout(school);
输出私有的属性
//访问属性
Field f1 = clazz.getDeclaredField("privateField");//得到名称为privateField的属性
f1.setAccessible(true);//解除私有封装,下面可以强制调用私有属性
f1.set(stu,"测试私有属性");
sout(f1.get(stu));
java动态代理
写一个接口
写一个实现类实现这个接口
写一个主方法
在执行里面的方法时需要加入一些东西,执行后打印执行完毕
做一个代理类
需要实现InvocationHandler接口
在主程序使用代理类
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。