反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。
Java反射机制主要提供了以下功能:
在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
生成动态代理
Class 是一个类; 一个描述类的类.
封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性.
下面我们以student为例 一一介绍
先说获取Class对象的三种方式
1.通过类名获取 类名.class
2.通过对象获取 对象名.getClass()
3.通过全类名获取 Class.forName(全类名)
//类名.class
Class<ConStudent> conSC = ConStudent.class;
System.out.print("---------类名.class---------"+"\n");
//对象名.getClass()
ConStudent conStudent = new ConStudent();
Class<? extends ConStudent> conSC1 = conStudent.getClass();
System.out.print("---------对象名.getClass()---------"+"\n");
//Class.forName(全类名)
Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
System.out.print("---------Class.forName(全类名)---------");
---------类名.class---------
静态代码:10
---------对象名.getClass()---------
静态代码:10
---------Class.forName(全类名)---------
public class ConStudent {
public static int number = 10;
static {
System.out.print("静态代码:"+number+"\n");
}
}
通过以上方式可以看出 第二第三种方式是直接调用静态代码的 从方便和效率来看 第三中方式是最好的 第一种也不错 第二种是不推荐的 个人建议 仅供参考
现在说一下 Constructor
先看一下 实体类
/**
-
Constructor
*/
public class ConStudent {public ConStudent(){
System.out.print("ConStudent空参构造函数"+"\n");
}public ConStudent(double score) {
System.out.print("ConStudent有参构造函数"+"\n");
}private ConStudent(int age) {
System.out.print("ConStudent私有构造带参数"+age+"\n");
}
protected ConStudent(String name){
System.out.print("ConStudent受保护的构造参数"+name+"\n");
}
}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> conSC = Class.forName("com.reflection.ConStudent");
Constructor<?>[] constructors = conSC.getConstructors();
for (Constructor c :constructors){
System.out.print("ReflectTest所有公有构造:"+c+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
for (Constructor c : declaredConstructors){
System.out.print("ReflectTest所有构造方法:"+c+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Constructor constructor = conSC.getConstructor();
System.out.print("ReflectTest公有无参构造方法"+constructor+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
System.out.print("ReflectTest私有构造方法"+declaredConstructor+"\n");
declaredConstructor.setAccessible(true);
Object o = declaredConstructor.newInstance(11);
System.out.print("ReflectTest调用私有构造"+o+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
declaredConstructor1.setAccessible(true);
Object maoge = declaredConstructor1.newInstance("maoge");
System.out.print("ReflectTest受保护的构造:"+maoge);
}
输出内容
ReflectTest所有公有构造:public com.reflection.ConStudent(double)
ReflectTest所有公有构造:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest所有构造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有构造方法:private com.reflection.ConStudent(int)
ReflectTest所有构造方法:public com.reflection.ConStudent(double)
ReflectTest所有构造方法:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest公有无参构造方法public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest私有构造方法private com.reflection.ConStudent(int)
ConStudent私有构造带参数11
ReflectTest调用私有构造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割线-------------
ConStudent受保护的构造参数maoge
ReflectTest受保护的构造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0
下面看一下 Filed
实体也是三个参数 代表三种权限
/**
-
Filed
*/
public class FiledStudent {
public int age;
private String name;
protected double score;@Override
public String toString() {
return "FiledStudent{" +
"age=" + age +
", name='" + name + ''' +
", score=" + score +
'}';
}public int getAge() {
return age;
}public void setAge(int age) {
this.age = age;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public double getScore() {
return score;
}public void setScore(double score) {
this.score = score;
}
}
private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
Field[] fields = filedSC.getFields();
for (Field f :fields){
System.out.print("ReflectTest所有公有的参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field age = filedSC.getField("age");
Object o = filedSC.getConstructor().newInstance();
age.set(o,11);
FiledStudent student = (FiledStudent) o;
System.out.print("ReflectTest获取公有参数:"+student.getAge()+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field[] declaredFields = filedSC.getDeclaredFields();
for (Field f :declaredFields){
System.out.print("ReflectTest获取所有参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field name = filedSC.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"Maoge");
System.out.print("ReflectTest获取指定的私有参数:"+student.getName()+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field score = filedSC.getDeclaredField("score");
score.setAccessible(true);
score.set(o,9.8);
System.out.print("ReflectTest获取受保护的参数:"+student.getScore());
}
下面看 mothed
/**
-
Method
*/
public class MethodStudent{
int age;
String name;
double score;public void showName( ){
System.out.print("(公共)姓名:");
}
private void showAge(){
System.out.print("(私有)年龄:");
}
protected void showScore(){
System.out.print("(保护)分数:");
}public String printName(String name){
System.out.print("(公共string)name:"+name);
return name;
}
private double printScore(double score){
System.out.print("(私有double)score:"+score);
return score;
}
protected int printAge(int age){
System.out.print("(保护age)age:"+age);
return age;
}
}
private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
Method[] declaredMethods = methodSC.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.print("ReflectTest 获取所有的方法:"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method[] methods = methodSC.getMethods();
for (Method m : methods){
System.out.print("ReflectTest获取所有的公有方法"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method score = methodSC.getDeclaredMethod("printScore", double.class);
Object o = methodSC.getConstructor().newInstance();
score.setAccessible(true);
Object invoke = score.invoke(o, 9.8);
System.out.print("ReflectTest调用制定的私有方法:"+invoke+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method printName = methodSC.getMethod("printName", String.class);
Object maoge = printName.invoke(o, "Maoge");
System.out.print("ReflectTest公有有参数方法:"+maoge+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method showName = methodSC.getMethod("showName", null);
System.out.print("ReflectTest公有无参方法:"+showName+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
printAge.setAccessible(true);
Object invoke1 = printAge.invoke(o, 20);
System.out.print("ReflectTest受保护的方法:"+invoke1);
}
这是反射的一些基础使用
下面说一下动态代理 (代理可以让我们的方法或者类进行功能扩展 解耦等好处)
新建一个接口
public interface Person {
void work();
}
新建一个接口实现类(被角色代理)
public class PersonImpl implements Person{
@Override
public void work() {
System.out.print("i am PersonImpl.calss");
}
}
新建一个代理角色
public class PersonHandler implements InvocationHandler {
public Object px;
public PersonHandler(Object px) {
this.px = px;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print("do work"+"\n");
return method.invoke(px,args);
}
}
绑定代理
public class PersonProxyTest {
public static void main(String[] args) {
Person person = new PersonImpl();
Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
o.work();
}
}
好了 本文到此结束 欢迎留言或私信
网友评论