Chp22-反射

Chp22-反射

概念

是一种底层技术, 核心为通过操作类对象来实现最终的目的, 通常用于底层框架的编写

类对象

  • 类对象:是类加载的产物, 内部存放着类的所有信息, 如包信息,父类信息,接口信息, 属性信息,方法信息,构造信息等, 只有一个
  • 类的对象: 是类实例化的产物, 存储着对象的具体信息, 可以为0-n个

获取类对象-Class

  1. getClass()

    Class 引用名=实例对象引用名.getClass();
    
    Student stu = new Student();
    Class c1 = stu.getClass();
    
  2. 类名.class

    Class<Student> c2 = Student.class;
    
  3. Class.forName(“全限定名”)

    try {
                Class c3 = Class.forName("com.by.entity.Student");
            } catch (ClassNotFoundException e) {
                System.out.println("类加载异常!");
                e.printStackTrace();
            }
    

构建实例

  1. 利用无参构造

    • 类对象.newInstance(): 利用类对象中的无参构造构建类的实例对象

      //利用无参构造构建类的实例-类对象无泛型时需要强转
              Student stu1=(Student) c1.newInstance();
              Student stu2 = c2.newInstance();
      
  2. 利用有参构造

    • 类对象.getDeclaredConstructor(参数1类对象,参数2类对象,..): 获取指定参数列表的有参构造器对象
    • 构造器对象.newInstance(实参列表): 利用有参构造器构建类的实例
    //1. 获取有参构造器
            Constructor<Student> con = c1.getDeclaredConstructor(String.class, int.class, double.class);
            //2. 构建实例
            Student stu3 = con.newInstance("lisi", 21, 88.5);
    

优缺点

  1. 优点
    • 打破封装
    • 提高操作的扩展性
  2. 缺点:
    • 打破封装
    • 降低数据的安全性
    • 书写

设计模式

是一种编码套路

单例模式

一个类只能创建一个实例

饿汉式

直接创建唯一实例

package com.by.entity;

/**
 * 单例模式-饿汉式
 */
public class ClassA {
    //static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
    //private: 防止外界直接访问属性
    private static ClassA ca = new ClassA();

    //外界获取唯一实例的渠道
    //static:使外界直接通过类名访问
    public static ClassA newClassA(){
        return ca;
    }

    //构造私有化-防止外界调用构造创建对象
    private ClassA(){

    }
}

缺点: 有可能浪费空间

懒汉式

在获取实例时创建唯一对象

package com.by.entity;

/**
 * 单例模式-懒汉式
 */
public class ClassB {
    //static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
    //private: 防止外界直接访问属性
    private static ClassB cb = null;

    //外界获取唯一实例的渠道
    //static:使外界直接通过类名访问
    //synchronized: 同步方法  预防线程安全问题
    public static synchronized ClassB newClassB(){
        
        if (cb == null) {//当第一次获取时再进行实例化 
            cb = new ClassB();
        }
        return cb;
    }

    //构造私有化-防止外界调用构造创建对象
    private ClassB(){

    }

}

缺点: 线程效率慢

懒汉式-进阶版

在懒汉式的基础上,利用同步代码块结合二次校验提高执行效率

package com.by.entity;

/**
 * 单例模式-懒汉式进阶版
 */
public class ClassC {
    //static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
    //private: 防止外界直接访问属性
    private static ClassC cc = null;

    //外界获取唯一实例的渠道
    //static:使外界直接通过类名访问
    public static ClassC newClassC(){
        if (cc == null) {//二次校验: 决定是否需要开启互斥锁 t1:true  t2:true
            synchronized (ClassC.class) {//临界资源对象: 当前类的类对象
                //对属性进行实例化
                if (cc == null) {//当第一次获取时再进行实例化
                    cc = new ClassC();
                }
            }
        }
        return cc;
    }

    //构造私有化-防止外界调用构造创建对象
    private ClassC(){

    }

}

工厂模式

  • 是一种底层技术,通常用于底层框架的编写
  • 思路: 将数据的创建和维护交由工厂完成
案例
  • 需求: 构建一个工厂类,获取学生对象
  1. 提供学生类

    package com.by.entity;
    
    public class Student {
        private String name;
        private int age;
        private double score;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public double getScore() {
            return score;
        }
    
        public void setScore(double score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", score=" + score +
                    '}';
        }
    
        public Student() {
        }
    
        public Student(String name, int age, double score) {//string,int,double
            this.name = name;
            this.age = age;
            this.score = score;
        }
    }
    
  2. 书写配置文件

    • 在项目下创建后缀名为.properties的配置文件
    • 作用: 存放被管理类的全限定名
    • 键=值的形式存放数据
    • 键值不可添加双引号、末尾不可添加分号、中间不可存在多个符号(如空格)
    • 一行只能有一个键值对
    StudentClassName=com.by.entity.Student
    
  3. 书写工厂类

    package com.by.util;
    
    import com.by.entity.Student;
    
    import java.io.FileInputStream;
    import java.util.Properties;
    
    public class MyFactory {
        /**
         * 获取学生对象
         */
        public static Student getStudent(){
            Student student = null;
            try (
                    //创建输入流
                    FileInputStream fis=new FileInputStream("factory.properties")
                    ) {
                //将配置文件的内容加载到集合中
                Properties p = new Properties();
                p.load(fis);
                //获取全限定名
                String className = p.getProperty("StudentClassName");
                //获取类对象
                Class c = Class.forName(className);
                //利用反射构建学生实例
                student = (Student) c.newInstance();
            } catch (Exception e) {
                System.out.println("未知异常!");
                e.printStackTrace();
            }
            return student;
    
        }
    }
    
    
  4. 测试

    package com.by.test;
    
    import com.by.entity.Student;
    import com.by.util.MyFactory;
    
    public class Test5 {
        public static void main(String[] args) {
            //利用工厂获取学生实例对象
            Student s1 = MyFactory.getStudent();
            Student s2 = MyFactory.getStudent();
    
        }
    }
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值