day18-反射

反射

类对象:
类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法) 。
每个类加载到内存都会生成一个唯一的类对象。

获取类对象的三种方式:

  • 通过对象的getClass方法(必须有类的对象,不常用)
  • 通过类的Class属性-> 类名.class(多用于方法传参)
  • 通过Class类的forName方法传入类的全限定名

Class对象的常用方法:

  • getSimpleName() 获取类名
  • getName() 获取类的全限定名
  • getSuperclass(); 获取父类的类对象
  • getInterfaces(); 获取所有父接口的类对象,返回数组
  • newInstance(); 通过类对象创建类的对象【这个类必须有无参构造,如果访问权限不够需使用暴力反射】

Field类表示类对象中的属性
Constructor类表示类对象中的构造方法
Method类表示类对象的方法
getDeclared-Field(s)-Constructor(s)-Method(s)可以获取到对应的所有包括私有(属性,构造,方法)
getModifiers()-判断修饰符(1为public,2为private)

设计模式

工厂模式

开发中有一个原则:“开闭原则”-对拓展开放,对修改关闭
工厂模式主要负责对象创建的问题
可通过反射进行工厂模式的设计,完成动态对象的创建
在这里插入图片描述

public class Demo03 {
    public static void main(String[] args) {
        Wife daWife = (Wife) BeanFactory2.getWife("dalaopo");
        daWife.sleep();
        Wife xiaoWife = (Wife) BeanFactory2.getWife("xiaolaopo");
        xiaoWife.sleep();
        Wife mnWife = (Wife) BeanFactory2.getWife("mnlaopo");
        mnWife.sleep();
    }
}
class BeanFactory2{
    //存入所有需要创建的类的对象
    static Map<String,Object> map =new HashMap<>();
    static {
        //加载配置文件
        Properties properties =new Properties();
        try {
            //调用ResourceAsStream流读取文件bean.properties将k,V写入properties集合内
            properties.load(BeanFactory2.class.getClassLoader().getResourceAsStream("bean.properties"));
            //读取properties内所有键值对
            Set<Map.Entry<Object, Object>> entries =  properties.entrySet();
            //根据properties内key对应值(要创建的类的全限定名)通过反射创建对应类的对象并存入静态map表中
            for (Map.Entry<Object, Object> entry: entries) {
                map.put((String) entry.getKey(),Class.forName((String)entry.getValue()).newInstance());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Object getWife(String name){
        return  map.get(name);
    }
}
interface Wife{ void sleep();}
class aWife implements Wife{
    @Override
    public void sleep() {
        System.out.println("大老婆温柔哄睡");
    }}
class bWife implements Wife{
    @Override
    public void sleep() {
        System.out.println("小老婆甜美哄睡");
    }}
class cWife implements Wife{
    @Override
    public void sleep() {
        System.out.println("美女老婆贴身哄睡");
    }}

单例模式

让类的对象只能有唯一的一个实例

懒汉式

  • 好处:避免资源浪费(需要对象的时候就创建对象)
  • 缺点 :线程不安全

解决:
1、DCL(双重检测锁)
DCL的问题:1、指令重排 2、多线程可见性
解决:volatile关键字修饰
2、使用静态内部类(什么时候使用静态内部类,什么时候就加载)

public class Singleton02 {
    private static volatile Singleton02 singleton02; //volatile
    private static Object obj = new Object();
    private Singleton02(){  
    }
    public static Singleton02 getInstance(){
        //双重检验锁  DCL(double check lock) 1、指令重排  2、可见性(在多线程间可见)
        if(singleton02 == null){
            synchronized (obj){//互斥锁标记
                if(singleton02 == null){
                    //java中允许指令重排序
                    singleton02 =  new Singleton02();
                }
            }
        }
        return singleton02;
    }
}

饿汉式

  • 好处:线程安全。
  • 缺点:浪费资源。只要类被加载,那么这个类实例就会被创建
public class Singleton01 {
    private static Singleton01 singleton01 = new Singleton01();

    private Singleton01(){
    }
    public static Singleton01 getInstance(){
        return singleton01;
    }
}

枚举

  • 枚举是一个引用类型,枚举是一个规定了取值范围的数据类型。
  • 一般已经确定类的对象个数,可以使用枚举定义
  • 定义枚举使用enum关键字。
  • 枚举中常量是当前类型的静态常量。
  • 枚举是一个终止类,并继承Enum抽象类。
  • 枚举中必须要包含枚举常量,也可以包含属性、方法、私有构造方法。
  • 枚举常量必须在前面,多个常量之间使用逗号隔开

注解

  • 注解(Annotation):是代码里的特殊标记, 程序可以读取注解,一般用于替代配置文件。
  • 可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
  • 定义注解使用@interface关键字,注解中只能包含属性。
  • 如果注解中属性是Value时,且只有一个Value属性必填时Value可以省略
  • 如果注解中属性有默认值可以不用设置
  • 注解中的属性类型可以是基本类型、String类型、注解类型、数组
  • 如果注解中的属性为数组类型,且属性值为一个时大括号可以省略

元注解

加在注解上的注解
@Retention:定义注解的使用范围

  • Class (默认的) class源文件期间保留
  • Source 编译期间保留
  • Runtime 在运行期保留

@Target: 定义注解的使用范围

  • TYPE, 类上使用
  • FIELD, 属性上使用
  • METHOD, 方法上使用
  • PARAMETER, 参数上使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值