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();
}
}
}