13. 泛型_枚举_单例

1. 泛型<>

在集合里面使用泛型 限定集合元素的数据类型

参数化数据类型 类型的自动转换。 只在编译期间有效 运行期间 泛型没有意义的 Object

List Map<K,V> E K V T A-Z 都是代表参数化数据类型

1.1 泛型类

public class MyFanXingClass<S extends Number, T> {
    //属性和方法
    private Integer id;
    private S s;//实例变量  对象  Object
    private T t;
    private Object data;

    public void a(T t1) { //普通的功能方法  t1的类型 与 T 类型一致

    }
    //创建泛型方法  b
    public <K,S,T,M,N> void b(K k,S s1,T t) {

    }

    //K S与创建对象的时候类型不一致   没有一点关系  在正常开发中 将泛型方法定义成static
    public static <K,S> void b1(K k,S s1) {

    }

    //参数化类型  上限  和 下限
    //上限: extends  MyFanXingClass<S extends Number, T>  限定了S只能是Number类型或者Number类型所有的子类
    //下限: super    MyFanXingClass<S, ? super  T> my   ?  限定了?只能T类型 或者 T 类型父级类型

    public  void c(MyFanXingClass<S, ? super  T> my, List<? super LinkedHashMap> list){

    }

1.2 泛型接口

//很多模块都有CURD  CREATE UPDATE READ  DELETE
public interface BaseDao<T, S> {
    //抽象出来很多模块通用的方法
    void add(T t);

    void delete(S id);

    void update(T t);

    List<T> selectAll();

    T selectOne(S id);
}
public abstract class BaseDaoImpl<T, S> implements BaseDao<T, S> {
    @Override
    public void add(T t) {
        System.out.println("add .... success " + t);
    }
//........
}
public interface UserDao extends BaseDao<User,Integer> {//继承父接口  可以使用多态创建对象
    //体现具体模块里面特有功能方法
}
public class UserDaoImpl extends BaseDaoImpl<User,Integer> implements UserDao {
}

2. 枚举

enum 修饰

public enum MyEnum {

    //组成部分
    //1.对象(实例 不可变的  线程安全的  常量)
    //默认调用无参构造创建对象 如果无参没有  报错
    //使用其他的带参构造创建对象
    OBJ1(1001, "jim") {
        //重写MyEnum的方法  等同于子类思想
        public int num = 100;

        public void b() {
            System.out.println(num);
        }

        @Override
        public void a() {
            b();
            System.out.println("MyEnum.....OBJ1....a....."+num);
        }
    },
    OBJ2(1002, "tom"),
    OBJ3(1003, "lily");

    //类: 属性  方法  构造
    //查看当前属性的数据
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void a() {
        System.out.println("MyEnum.....a....");
    }

    //构造: 都是私有的
//    MyEnum() {
//        System.out.println("构造方法 初始化成员变量");
//        this.id = 1001;
//        this.name = "admin";
//    }

    MyEnum(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
}

枚举类+泛型类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VhpBY3RC-1608733531586)(pic/json.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uNXRy83J-1608733531588)(pic/json1.png)]

都有message,status
success:  多了一个data
在浏览器客户端请求,服务器响应。    有请求必然有响应: 
@Setter
@Getter
@ToString
public class ServerResponseResult<T> {

    private String message;
    private Integer status;
    private T data;

    //成功
    public static <T> ServerResponseResult<T> success(T data) {
        return new ServerResponseResult<>(CodeEnum.SUCCESS.getMsg(), CodeEnum.SUCCESS.getCode(), data);
    }

    public static <T> ServerResponseResult<T> success(String msg, T data) {
        return new ServerResponseResult<>(msg, CodeEnum.SUCCESS.getCode(), data);
    }

    //失败
    public static <T> ServerResponseResult<T> error() {
        return new ServerResponseResult<>(CodeEnum.ERROR.getMsg(), CodeEnum.ERROR.getCode());
    }

    private ServerResponseResult(String message, Integer status) {
        this.message = message;
        this.status = status;
    }

    private ServerResponseResult(String message, Integer status, T data) {
        this.message = message;
        this.status = status;
        this.data = data;
    }
}
public enum CodeEnum {
    SUCCESS("success", 200),
    ERROR("error", 403);

    private String msg;
    private Integer code;

    public String getMsg() {
        return msg;
    }

    public Integer getCode() {
        return code;
    }

    CodeEnum(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }
}

3. 单例模式

一个对象。 在一个进程里面 有且只有一个对象。

创建对象:
  new
  clone
  序列化

3.1 饿汉模式

1.构造方法private
2.创建静态成员变量  并初始化 
3.提供静态的方法
    
public class User {
    private User(){}
    //只要加载User.class  必然会执行static
    private static User user = new User();
    //提供public  static
    public static User getInstance(){

        return user;
    }
}   
没有线程安全的问题  
没有体现懒加载 lazy loding 的特征(何时使用对象  何时创建实例)

3.2 懒汉模式

1.构造方法private
2.声明静态的成员
3.提供静态的方法
    
com.javasm.singlton.User@d2d28d0
com.javasm.singlton.User@62660012
    .....
 private User() {
   }

private static User user;//null

public static User getInstance() {
    if (user == null) {
        user = new User();
    }//体现的懒加载的特征

    return user;
}
有线程安全问题:
  解决方式:
     同步方法   效率很低
     同步代码块:  效率很低

public static User getInstance() {//加锁
        synchronized ("abc") {
            if (user == null) {
                user = new User();
            }//体现的懒加载的特征
        }
        return user;
    }
推荐:
   同步代码块: DCL doucle check lock  + volatile
    public static User getInstance() {
        if (user == null) {
            synchronized ("abc") {
                if (user == null) {
                    user = new User();
                }
            }
        }
        return user;
    }    
隐藏的隐患:
  jvm  提高程序的执行效率  有可能会进行指令重排
  创建对象:
    1. 开辟内存空间  2ms
    2. 执行构造  初始化成员变量数据  10ms
    3. 内存地址值赋值引用  3ms
    15ms
    指令重排:
      1   3   5ms 
   volatile: 能解决可见性(缓存一致性) 有序性 限制指令重排  不能解决原子性
//序列化(反射,克隆)打破了单例特性
com.javasm.singlton.User@1540e19d
success
com.javasm.singlton.User@16b98e56
    
//readResolve
public Object readResolve() {
    return user;
}    

4. volatile

原子性  short i = 1; i++;  short temp =i;  temp = i+1;  i = temp;
可见性   
有序性    
创建id生成器:
public class IdGenrator {

//    private static volatile int idIndex = 0;

    //AtomicInteger/AtomicLong/LongAdder
//    private static AtomicLong idIndex = new AtomicLong(0);

    private static LongAdder idIndex = new LongAdder();

    static {
        idIndex.add(10000);//设置初始值
    }

    //维护id自增
    public static void idIncrement() {

//        idIndex = idIndex+1;
//        idIndex++;
        //int temp = idIndex;
//        temp = idIndex+1;
//        inIndex = temp;
//        idIndex.incrementAndGet();
        idIndex.increment();
    }

    public static void idDecre() {
        idIndex.decrement();
    }

    public static long getId() {
//        return idIndex.get();
        return idIndex.longValue();
    }
}  

5. 注解

@解释名称 注解的标识

注释: 给程序员
注解: 给程序看的
@SuppressWarnings("all")
@Override
@Deprecated
1.配置方式  开发  xml 文件  配置文件是固定 方便统一维护  效率偏低
2.全注解开发  效率高  耦合度很高  维护比较困难  SpringBoot

5.1 元注解

对注解进行解释说明。

@Retention 规定注解在何时是有效的  RetentionPolicy: SOURCE  CLASS  RUNTIME
@Target  规定注解在哪里可以被使用   ElementType:
@Documented   javadoc指令 注解也会在api里面生成
@Inherited  类的注解对子类有效的
@FunctionalInterface 函数式接口  lamda  用在只要1个抽象方法接口上

5.2 自定义注解

//元注解
public @interface 注解名称{ 
    //参数
}
//@Retention(value = RetentionPolicy.RUNTIME)//如果注解里面 有一个参数  而且参数名为value 可以省略
@Retention(RetentionPolicy.RUNTIME)
//@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER})
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Documented
@Inherited
public @interface MyAnno {

    //参数: 获得参数的数据(一般2-3个)
    //字面量类型    枚举类型  Class  以上类型的数组

    int id() default 1001;

    String name() default "无名氏";

    double score() default 60;

    String[] hobby() default {};

    DayOfWeek day() default DayOfWeek.MONDAY;

    //? 通配
    Class<?> clazz() default Object.class;
//    Class<?>[] clazz1();
    //DayOfWeek[] day1();
}

6. 反射

java语言具有动态性。java并不是一门动态语言。

程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言

java语言具有反射机制 。 在jvm加载class文件运行期间 探知class文件中组成部分

用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语

只要jvm加载class文件 创建一个与之相对应的Class对象

首先,反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。
其次,通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类。
再次,使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。
最后,反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中
操作class文件内容:
属性---->Filed
方法---->Method
构造----->Constructor
注解----->Annotation

6.1 操作属性

User.java
用户注册:
   用户在浏览器提交过来注册的信息
模拟对象自动装配:
   自动装配成用户对象       
 public static Object demo1() {
        //自动装配User对象
        String name = "jim";
        String pass = "1234";
        String phone = "74364654657";
        //后台代码接收前台页面提交数据: 集合接收所有的数据

        Map<String, Object> params = new HashMap<>(16);
        params.put("name", name);
        params.put("pass", pass);
        params.put("phone", phone);

        //url  http://www.baidu.com/demo/user/login.html?name=jim&pass=1234

        //操作的是Class文件--->通过反射创建对象 (并将数据装配到对象里面)
        //肯定要关联是那一个类的class--->获得Class<?> 对象
        //对象.getClass
        //类名.class
        //Class.forName()
        try {
            //1.获得Class对象
            Class<?> clazz = Class.forName("com.javasm.reflect.User");
            System.out.println(clazz);

            //2.创建User对象
            User user = (User) clazz.newInstance();//前提: 默认执行类的无参构造
//            System.out.println(user);
            //学习框架  一定要提供无参构造

            //3.将数据注入到对象
            //3.1 直接访问属性
//            Field[] fields = clazz.getFields();//获得public修饰的属性
//            System.out.println(Arrays.toString(fields));
//
//            Field[] declaredFields = clazz.getDeclaredFields();//获得类里面所有的属性
//            System.out.println(Arrays.toString(declaredFields));


            params.forEach((fieldName, fieldValue) -> {
                try {
                    //找到具体的Filed对象
                    Field field = clazz.getDeclaredField(fieldName);
                    //对属性赋值  set(Object obj, Object value)  obj:对象  value: 属性数据
                    field.setAccessible(true);
                    field.set(user, fieldValue);
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }

            });

            System.out.println(user);
            //3.2 执行set方法(setter注入)

            return user;

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

        return null;

    }

6.2 操作方法

//模拟: 获得前台页面的数据  自动装配对象 并将参数数据注入到对象中
    public static Object methodTest() {
        //http://www.baidu.com/demo/user/login.html?name=jim&pass=1234&phone=111111111111
        //1.获得前台页面数据  使用集合维护(前期已经自动转换类型)
        Map<String, Object> params = new HashMap<>(16);
        params.put("name", "jim");
        params.put("pass", "1234");
        params.put("phone", "111111111111");


        try {
            //2.通过反射创建对象
            Class<?> userClass = Class.forName("com.javasm.reflect.field.User");
            User user = (User) userClass.newInstance();

            //3.将参数数据注入到user对象中(最常用set注入)  等同于调用属性的set方法

//            System.out.println(Arrays.toString(userClass.getMethods()));//获得public的方法(包含父类的)
//            System.out.println(Arrays.toString(userClass.getDeclaredMethods()));//获得本类里面所有的方法(不包含父类)

            //getMethod(String name, Class<?>... parameterTypes)  name: 方法名称   parameterTypes: 方法形参类型
            //set方法:  set+name

            params.forEach((fieldName, value) -> {
                //属性名称在set方法里面: 首字母要大写
                try {
                    //获得指定的set方法
                    StringBuilder builder = new StringBuilder(fieldName);
                    builder.setCharAt(0, Character.toUpperCase(fieldName.charAt(0)));
                    String methodName = "set" + builder.toString();
                    Method method = userClass.getMethod(methodName, value.getClass());

                    //执行方法逻辑(唤醒方法)  invoke(Object obj, Object... args)  obj:对象  args: 实参
                    System.out.println(method.invoke(user, value));
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            });

            return user;

        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }


        return null;
    }

6.3 操作构造

 public static Object demo() {

        Map<String, Object> params = new LinkedHashMap<>(16);
        params.put("name", "tom");
        params.put("pass", "1234");
        params.put("phone", "22222222222");

        try {
            //构造注入
            Class<?> userClass = Class.forName("com.javasm.reflect.field.User");
//            System.out.println(Arrays.toString(userClass.getConstructors()));//获得本类里面public修饰的构造
//            System.out.println(Arrays.toString(userClass.getDeclaredConstructors()));//获得本类里面所有的构造

            //(Class<?>... parameterTypes)
            Constructor<?> constructor = userClass.getDeclaredConstructor(String.class, String.class, String.class);
            //调用构造器对象里面的方法 newInstance(Object ... initargs)
            constructor.setAccessible(true);
            User user = (User) constructor.newInstance(params.values().toArray(new Object[0]));

            return user;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

6.4 操作注解

http://t.weather.itboy.net/api/weather/city/101010500
//模拟路径  查询数据
public static void main(String[] args) {

        //从后往前
        //获得selectWeatherData上面的注解里面参数数据

        try {
            Class<?> aClass = Class.forName("com.javasm.reflect.anno.WeatherData");

            System.out.println(aClass.getName());//类/接口/枚举 全限定名称  路径
            System.out.println(aClass.getSimpleName());//类名  接口名
            
//            ToString annotation = aClass.getAnnotation(ToString.class);

//            Method method = aClass.getDeclaredMethod("selectWeatherData");
//            PathAnno pathAnno = method.getAnnotation(PathAnno.class);
//            String value = pathAnno.value();
//            System.out.println(value);
//            System.out.println(pathAnno.num());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}
        Class<?> aClass = Class.forName("com.javasm.reflect.anno.WeatherData");

        System.out.println(aClass.getName());//类/接口/枚举 全限定名称  路径
        System.out.println(aClass.getSimpleName());//类名  接口名

// ToString annotation = aClass.getAnnotation(ToString.class);

// Method method = aClass.getDeclaredMethod(“selectWeatherData”);
// PathAnno pathAnno = method.getAnnotation(PathAnno.class);
// String value = pathAnno.value();
// System.out.println(value);
// System.out.println(pathAnno.num());

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

}














  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值