反封装技术 , 我们可以通过反射, 得到一个类的对象的 私有方法 和 私有属性 !
反射: 编写代码时, 动态的加载类, 动态的使用一个编译器不存在的类 !
Class类
每一个.java文件, 编译后的class 在执行时 都会被加载到内存中, 在内存中是以Class类的对象形式存在的!
获取一个类的 类对象的方式:
1. 通过类创建的对象 获取类对象
格式: Class c = 对象.getClass();
2. 通过类的全名, 得到一个类对象
格式: Class c = 包名.类名.class;
3. 通过类名的字符串, 加载一个类的类对象
格式: Class c = Class.forName(String className);
上述的三种获取方式, 在调用时, 如果类对象 在内存中已经存在, 则获取存在的对象, 如果不存在 ,则加载到内存!
(在内存中, 不会同时存在一个类的 两个类对象)
特殊的类对象:
8种基本数据类型, 也可以获取类信息 . 以及Void 也可以获取类信息, 通过.class即可!
通过class对象, 直接获取一个类的对象
调用无参构造器 创建对象, 如果类不存在无参构造器, 则报错
Object o = class.newInstance();
通过class对象, 获取一个类的构造方法
1. 通过指定的参数类型, 获取指定长度与类型的构造方法!
格式:
Constructor con = class.getConstructor(类型对象数组);
2. 得到构造方法后, 如何通过构造方法 得到对象
Object o = con.newInstance(Object... para);
通过class对象获取一个类的所有方法
- 根据方法名称和形式参数列表类型, 得到一个方法对象(方法必须是public的,包含继承)
1. Method m = class.getMethod(String methodName,Class.. cla);
- 得到一个类的所有public方法(包含继承的)
2. Method[] ms = class.getMethods();
- 根据方法名称和形式参数列表类型, 得到一个方法对象(除继承以外的所有方法)
3. Method m = class.getDeclaredMethod(String methodName,Class.. cla);
- 得到一个类的所有public方法(除继承以外的所有方法)
4. Method[] ms = class.getDeclaredMethods();
通过方法对象, 调用方法:
参数1. 要调用此方法的 对象
参数2. 调用方法时传递的参数
invoke(Object o ,Object... para);
获取方法的名称
String name = getName();
访问私有方法时, 需要取消权限检查
setAccessible(boolean flag);
值为true则表示取消权限检查(可以访问任何权限的方法)
通过class对象获取一个类的所有属性
1. Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
2. Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
3. Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
4. Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
属性对象常用方法:
- 属性对象.get(Object o);
参数: 要获取属性的对象
作用: 得到参数1对象的 属性值 !
- 属性对象.set(Object o,Object value);
参数1: 要设置属性的对象
参数2: 要设置的属性的值
- String name = 属性对象.getName();
获取属性的名称
- 访问私有属性时, 需要取消权限检查
属性对象.setAccessible(boolean flag);
值为true则表示取消权限检查(可以访问任何权限的方法)
Java反射之内省
基于反射实现的一套工具API , 用于操作JavaBean的Api
JavaBean类:
一个类,
拥有无参构造器 ,
所有属性私有, 提供get/set方法,
定义在包中 , 实现了序列化接口
String name
public void setName(String name){
//对于name设置的规则
this.name = name;
}
public String getName(){
return this.name;
}
Introspector
获取Bean类信息
方法:
BeanInfo info = getBeanInfo(Class beanClass);
BeanInfo
获取Bean类的 get/set方法数组
MethodDescriptor[] mds = getPropertyDescriptors();
MethodDescriptor
包含一个GET/SET方法的对象 !
- 获取其中的GET方法
Method getReadMethod();
- 获取其中的SET方法
Method getWriteMethod();
在使用时, 建议判断是否为null , 因为总有些属性 是仅拥有GET 或 仅拥有SET的 !
快捷键:
1. alt+/ : 代码联想 补全
2. ctrl+1 : 提示, 帮助
3. ctrl+2 : 接收返回值 , 生成变量
4. ctrl+d : 删除当前行代码
5. ctrl+alt+↑ : 将当前代码向上复制一行
6. ctrl+alt+↓ : 将当前代码向下复制一行
7. alt+↑ : 将当前行代码 上移一行
8. alt+↓ : 将当前行代码 下移一行
4. ctrl+t : 查看类结构(子父类结构)
5. ctrl+o : 查看类成员(方法/属性)
六大设计原则
1. 开闭原则
对扩展开放, 对修改关闭 ! 为了使程序拥有更好的扩展性, 便于我们后进行维护和升级 !
2. 里氏代换原则
在代码中, 任何可以使用父类进行操作的地方 , 都应可以使用子类进行代换操作 !
3. 依赖倒转原则
面向接口编程, 依赖于抽象 , 而不是依赖于具体的实现 !
4. 接口隔离原则
使用多个不相关的接口, 把一个抽象的事物 隔离开 , 比使用单个接口描述一个抽象的事物更好 !
5. 迪米特法则
一个具体的类(实体类) ,应尽可能的与其他的实体类 少发生相互作用!
6. 合成复用原则
实现一些扩展操作时, 尽量使用组合的方式, 而不是继承 !
(可以了解: 装饰者设计模式 与 继承的区别 ? )
不积跬步,无以至千里;不积小流,无以成江海。
但愿能够帮助看到这篇文章的你! ^_^ 加油