反射
1.反射机制
Java的反射机制是指在运行状态中,对于任何一个类,都可以知道这个类所有属性和方法,对于任何一个对象,都可以用这个对象调用所有方法和属性,这种动态获取数据和操作对象的方法和属性的能力叫反射机制.
2.反射
将java类中所有成员属性,方法,构造方法映射成一个个对象.
反射是所有框架的灵魂.
属性->映射成->Field的对象
方法->映射成->Method的对象
构造方法->映射成->Constructor的对象
3.反射对象(类对象)
当程序运行,第一次加载类时,先将硬盘上.class文件加载内存中,这时类加载器和JVM会根据.class文件生成.class对象,这个对象叫反射对象也叫类对象.
一个类只有一个反射对象.
4.获得反射对象:
注意:全限定类名:包名.类名
- 1:类名.class
- 2:对象名.getClass()
- 3:Class.forName(全限定类名);//推荐
public static void main(String[] args) throws ClassNotFoundException {
//创建类的对象
Student stu1=new Student();
Student stu2=new Student();
//获得这个类的反射对象
Class clazz=Class.forName("com.qf.day24.demo2.Student");
System.out.println(stu1.getClass()==stu2.getClass());//true
System.out.println(stu1.getClass()==Student.class);//true
System.out.println(stu1.getClass()==clazz);//true
System.out.println(Student.class==clazz);//true
}
5.用反射对象操作类的属性
public static void main(String[] args) throws ClassNotFoundException, Exception {
//获得学生类的反射对象
Class<Student> clazz=(Class<Student>) Class.forName("com.qf.day24.demo2.Student");
//通过反射对象获得学生类对象,底层调用Student类无参构造
Student stu=clazz.newInstance();
//通过类的反射对象获得属性对象
Field sageField=clazz.getDeclaredField("sage");
//设置属性的访问权限,让私有的可以访问
sageField.setAccessible(true);
System.out.println("属性访问修饰符:"+sageField.getModifiers());
System.out.println("属性的数据类型:"+sageField.getGenericType());
//通过反射给属性设值
sageField.set(stu, 88);
System.out.println("学生的年龄:"+sageField.get(stu));
}
6.用反射对象操作类的方法
public static void main(String[] args) throws ClassNotFoundException, Exception {
//获得学生类的反射对象
Class<Student> clazz=(Class<Student>) Class.forName("com.qf.day24.demo2.Student");
//通过反射对象获得学生类对象,底层调用Student类无参构造
Student stu=clazz.newInstance();
//通过反射对象获得方法
Method showMethod=clazz.getDeclaredMethod("show2",String.class);
//设置方法访问权限,让私有的方法可操作
showMethod.setAccessible(true);
System.out.println("方法的访问修饰符为:"+showMethod.getModifiers());
System.out.println("方法的返回值数据类型:"+showMethod.getGenericReturnType());
System.out.println("***方法的参数列表的数据类型:"+Arrays.toString(showMethod.getGenericParameterTypes()));
//用反射调用方法
showMethod.invoke(stu,"破坏活动诶非");
}
7.用反射对象操作类的构造方法
public static void main(String[] args) throws ClassNotFoundException, Exception {
//获得学生类的反射对象
Class<Student> clazz=(Class<Student>) Class.forName("com.qf.day24.demo2.Student");
//通过反射对象获得构造方法
Constructor<Student> stuConstructor=clazz.getDeclaredConstructor(String.class);
//设置访问权限,让私有构造方法可用
stuConstructor.setAccessible(true);
System.out.println("构造方法的访问修饰:"+stuConstructor.getModifiers());
System.out.println("构造方法的参数列表的数据类型:"+Arrays.toString(stuConstructor.getGenericParameterTypes()));
//通过反射调用构造方法,创建实例对象
Student stu2=stuConstructor.newInstance("张三");
System.out.println("学生姓名为:"+stu2.sname);
}
设计模式
1.设计模式
前人经过项目经验的总结,总结出对特定问题的特定解决方案.(23种)
设计模块共计23种,总体划分三大类
- 创建型模式(5种): 工厂方法模式; 抽象工厂模式; 单例模式; 建造者模式; 原型模式;
- 结构型模式 (7种):适配器模式;装饰器模式;代理模式;外观模式;桥接模式;组合模式,享元模式;
- 行为型模式(11种):策略模式;模板方法模式;观察者模式;迭代子模式;责任链模式;命令模式;备忘录模式;状态模式;访问者模式;中介者模式;解释器模式。
- 其实还有俩类:并发型模式和线程池模式
2.工厂模式
负责对象的创建问题
- 优点:将创建对象工作交给工厂,自己不用创建.
- 缺点:类与类之间耦合度太高.
- 案例:通过反射进行工厂模式的设计,完成动态的对象的创建.
/**
工厂类
*/
public class Factory1 {
/**
* 创建对象工厂方法
* @return
* @throws ClassNotFoundException
*/
public static Usb getUsbObject(String classname) throws Exception {
Class<Usb> clazz=(Class<Usb>) Class.forName(classname);
Usb u1=clazz.newInstance();
return u1;
}
}
public static void main(String[] args) throws Exception {
//测试工厂模式
Usb u1=Factory1.getUsbObject("com.qf.day25.demo5.MouseUsb");
Usb u2=Factory1.getUsbObject("com.qf.day25.demo5.FanUsb");
u1.work();
u2.work();
}
3.单例模式
一个类只有一个对象.
- 优点:减少频繁创建对象所消耗系统资源.
- 实现方式:私有化构造方法,声明私有静态当前对象变量,给他提供一个公有的静态的获得对象的方法.
3.1:饿汉式单例模式
相懒汉式单例模式来说,优点:在多线程中使用安全.缺点:耗系统资源.
/**
饿汉式单例模式
*/
public class King1 {
/**
* 私有构造方法
*/
private King1() {
}
//声明私有静态的当前类的对象
private static King1 k1=new King1();
/**
* 公有静态获得对象方法
* @return King1
*/
public static King1 getKing1() {
return k1;
}
}
3.2:懒汉式单例模式:相对于饿汉式单例模式:优点:不耗资源.缺点在多线程中使用不安 全.如果想在多线程中使用就用线程同步.
public class King2 {
/**
* 私有构造方法
*/
private King2() {
}
//声明私有静态的当前类的对象
private static King2 k1;
/**
* 公有静态获得对象方法
* @return King1
*/
public synchronized static King2 getKing2() {
if (k1==null) {
k1=new King2();
}
return k1;
}
}
4.(扩展)设计原则
前人经过经验的总结出写Java代码的规则,平时写代码遵循这些规则,写出代码就规范性好.java要求程序高内聚低耦合.
内聚性:独立性.
耦合度:依赖性.
- 1:单一职能原则:一个类一做一件事.
作用:提高程序内聚性,降低程序耦合度. - 2:里氏替换原则:所有使用父类父接口的地方,都可以用子类去替换.
作用:提高程序可扩展性. - 3:依赖倒置原则:能依赖抽象的就不依赖于具体的.
作用:提高程序可扩展性. - 4:接口隔离原则:一个接口只被设计一种功能.
作用:提高程序灵活性和可扩展性. - 5:迪米特原则:一个对象应该对其他对象保持最少的了解.
作用:提高程序内聚性,降低程序耦合度. - 6:开闭原则:对扩展开发,对修改关闭.
作用:提高程序的可维护性.
个人笔记,思路,仅供参考