javaweb3

day3:Java基础加强第一天
JDK5.0 新特性、反射 
day24:Java基础加强第二天
注解技术、动态代理、多线程编程、Socket网络编程


JDK5 新特性 九个: 泛型技术、枚举技术、自动装箱拆箱、静态导入、增强for循环、可变参数、字符串格式化、注解技术、多线程并发库
特性一:泛型技术(基础学习在集合中使用)


应用场景一: 集合对象中,如果不使用泛型,将任意类型数据保存到集合,取出数据时,类型会丢失,需要程序员进行强制类型转换(存在类型转换异常)
***** 基于安全性,对集合对象使用泛型


泛型应用于集合,保证集合中只能保存指定类型数据,只作用于源代码阶段,在编译时进行类型检查,当.java编译.class后,泛型信息将被擦除!
ArrayList<Integer> ---- ParameterizedType 参数化类型


掌握:使用泛型的类型安全集合对象使用 List、Set 、Map


泛型的类型转换 注意问题:等号两边泛型必须一致 
List<Integer> ints = new LinkedList<Integer>(); 正确
List<Number> nums = new LinkedList<Integer>();  虽然Integer是Number子类,等号两边泛型必须一致 ----- 错误


List list = new ArrayList(); 正确
List list = new ArrayList<String>(); 正确
List<String> list = new ArrayList(); 正确


应用场景二:通用类型 经常编写框架和复用度很高程序
C++ 模板  定义泛型  public class ArrayList<E> {}  E是占位符,代表泛型,在开发中,可以为ArrayList 传入指定类型
new ArrayList<Integer>
new ArrayList<String>


泛型方法定义:在方法返回值之前 加入<占位符>  T根据传入类型发生变化
列一 :编写一个泛形方法,实现指定位置上数组元素的交换。
// 交换任何类型数组 两个位置元素
private <T> void change(T[] arr, int i, int j) {
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
例二 :编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素。
// T 是Template缩写,模板方法, 通用数组倒序方法
private <T> void reverse(T[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
T temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}


自定义泛型类:将泛型信息放到类名后面,类中所有实例变量、实例方法 都可以直接使用该泛型,static变量和方法不可以
// 自定义泛型类
class GenericClass<T> {
// 实例变量
T t;


// 所有实例方法 都可以使用泛型
public void add(T t) {
}


public T getInfo() {
return null;
}


// 静态方法不能使用类上面泛型
public static <E> void show(E t) {
}
}


*** T Template缩写 ArrayList<E> Element缩写  Map<K,V> key、value缩写


泛型技术:任意类型(变量类型)  ----- 泛型通配符:任意泛型类型
泛型场景 change(T[] arr,int i,int j) ; 这里T 任意类型数组
通配符场景 print(List<?> list); 这个方法就是打印 List集合,该List 可以是任意泛型List 集合


List<?> list3 = new ArrayList<String>(); // ? 代表任意类型,String  满足  ---- 实例化时不能用 ?通配符,只能用于声明
上边界
? extend Number : Number的任意子类型(含Number本身)
List<? extends Number> list = new ArrayList<Number>(); 可以
List<? extends Number> list = new ArrayList<Integer>(); Integer是Number子类 可以


下边界
? super Integer : Integer的任意父类型(含Integer本身)
List<? super Integer> list = new ArrayList<Object>(); 可以 Object是Integer父类型


---------------------------------------------------------------------------------------------------------
特性二:枚举技术 


枚举出现 解决 一定范围取值的问题


enum定义枚举 public enum Color {}


枚举定义格式
enum 枚举类名 {
   实例一,实例二,实例三, ... , 实例n ;
}
** 实例 就是枚举类对象 public static final 


class Role2 {
public static final Role2 BOSS = new Role2();
public static final Role2 MANAGER = new Role2();
public static final Role2 HR = new Role2();
public static final Role2 WORKER = new Role2();


private Role2() {
}
}


enum Role3 {
BOSS, MANAGER, HR, WORKER;
}


* Role3 和Role2 是等价的 --- 翻译后 BOSS、MANAGER、HR、WORKER 都会成为常量对象


enum Role3 {
    BOSS ;
}
编译后
final enum cn.itcast.enumtest.Role3 {
    public static final enum cn.itcast.enumtest.Role3 BOSS;
}
构造器 private


JDK5.0之前 byte short char int 
JDK5.0之后 增添 enum支持
JDK7.0之后 增添 String支持


如果枚举只有一个对象,类似单例模式 
// 单例模式 --- 懒汉
class B {
private static B b;


private B() {
}


// 当使用B时候创建B的对象
public static B getInstance() {
if (b == null) {// 因为b是static 只实例化一次
b = new B();
}
return b;
}
}


// 单例模式 ---- 饿汉
// 1、private static 成员对象 2、private 构造器 3、static获得成员对象方法
class A {
private static A a = new A();// 定义A 时,直接创建对象 (饿汉)


private A() {
}


public static A getInstance() {
return a;
}
}


--------------------------------------------------------------------------------
枚举类API 由三部分组成
1. 自定义方法
2. 所有枚举类 extends java.lang.Enum 类 --- 使用Enum中方法 
String name()  返回枚举实例名称
int ordinal() 返回枚举实例下标 (第一个实例 下标是0)
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 将String 枚举实例名称转换枚举实例对象


3、在枚举类进行编译时,编译器会动态加入两个方法  
values() 返回当前枚举类所有实例数组
T valueOf(String name) 将枚举实例名称转换枚举实例对象 


思考
枚举对象、枚举对象下标、枚举对象名称表示之间的转换




特性三:静态导入  --- 导入的是静态属性和方法
* 导入后方法和属性,相当于当前类方法和属性,可以直接使用
语法: import static  ... ;


1、静态导入 使代码可读性变差 
2、如果存在两个方法相同,发送冲突


例如:写计算器,需要大量Math中函数 ---- import static java.lang.Math.*;


特性四:自动装箱、拆箱
JDK5 后可以将 基本数据类型 与包装类对象进行直接赋值


Integer o = 100; // 100 就是 int类型, int值赋值Integer 类型 ----- 自动装箱
int i = o ; // 将 Integer类型 直接赋值 int 类型 ---- 自动拆箱
----- JDK5之后
// 自动装箱
Integer o = 100;
// 自动拆箱
int i = o;


----- JDK5之前
// 将 int 转换 Integer
Integer o = new Integer(100);// 构造器
Integer o2= Integer.valueOf(100); 

// 将Integer转换为int 
int i = o.intValue();


练习
public void doSomething(double d){ }
public void doSomething(Integer i) { }


doSomething(100); ----- 执行 double参数方法,因为JDK1.4只能用double ,不能自动装箱 ---- JDK5以后要向1.4版本结果进行兼容 调用double参数方法


特性五:增强for循环 (for/in 语句)
增强for循环 出现原因:简化Iterator的复杂写法 


for/in语句的适用范围
1、遍历数组
2、遍历实现Iterable接口的集合类


增强for循环在编译后,就是Iterator实现 ------- 增强for循环 就是Iterator、效率相同


增强for循环使用时 注意:迭代取出数组或集合每个元素,如果取出元素类型 八种基本数据类型或者 String类型 ,对其操作,不会改变原集合或数组中元素


让自定义对象 用于forin 语句
1、自定义对象必须实现Iterable 接口
2、提供Iterator 迭代器


移除练习
java.util.ConcurrentModificationException ----- 并发修改异常 (增强for循环 遍历List,删除list中元素,从而改变list的长度)
Iterator 一定通过hasNext 和 next遍历集合,next时发生异常


final void checkForComodification() {
   if (modCount != expectedModCount)
throw new ConcurrentModificationException();
   }
}
---------- 修改List modCount修改次数 +1  与循环开始时 expectedModCount 不同发生异常


1、 解决方法:不执行ArrayList的remove 执行Iterator自己提供remove
2、 解决方法:不用迭代器 
3、 解决方案:在next时才会进行 比较,当删除后,立刻break,不会发生异常 (只能删除一个)
4、 解决方案:换线程安全集合对象 CopyOnWriteArrayList


特性六:可变参数
Arrays.asList 方法参数就是可变参数


可变参数在编译时,以数组保存,必须放到最后一个参数
add(int... arr,String... arr2) {} 错误的 ,只能有一个可变参数
add(int... arr,String s) {} 错误的
add(String s,int... arr) {} 正确的


----------------------------------------------------------------------------------------------------------------------------------
反射: JavaSE 高级特性,用来编写框架主要手段 (原理:根据JVM对类加载后在内存中形成对象,操作类结构信息)


1、获得Class对象 ----- 一个类.class文件 字节码对象
2、创建类对象
调用默认构造器 c.newInstance()
调用有参数构造器 c.getConstructor(Class<?>... parameterTypes)  获得Constructor对象,再构造newInstance(Object... initargs)  传入参数
Constructor constructor = c.getConstructor(String.class, String.class, double.class);
Object product2 = constructor.newInstance("p01", "笔记本电脑", 5000);


3、读写类成员变量
Field name = c. getDeclaredField("name"); // 获得一个指定成员变量对应Field对象
name.setAccessible(true); // 如果变量private 无法访问。打开可以访问权限
设值:f.set(obj,value) ;
取值:f.get(obj);


4、执行类的方法 
Method m = c.getDeclaredMethod(String name, Class<?>... parameterTypes) ;
// 获得方法 : 方法名称和参数列表
Method setName = c.getDeclaredMethod("setName", String.class);
// 执行方法 :对象和 实际参数列表
setName.invoke(p, "麦克风");


小案例: 晚会举办案例
1、what to do
2、how to do
3、如果晚会演员 使用具体实现类 Singable singer = new WangFei(); ---- 当演员需要更换时,改动晚会源码 
** 不想改晚会源码  ---- 解耦合 插入工厂(中介)


4、配置文件(将演员配置到文件中)---- 不用改代码 、该配置文件
在src下新建party.properties 配置文件


5、读取配置文件 获得完整实现类名称 (反射)


工厂+反射+配置文件 案例 ----- 学Spring有帮助


-------------------------------------------------------------------------------------------------------------------------
学习内容小结
1、泛型(类型安全List、Set、Map ;自定义泛型;通配符上下边界)
2、枚举编译后就是静态常量(由来)、WeekDay打印中文、枚举对象(名称、下标)转换
3、增强for循环编译后就是Iterator、注意问题内存两张图、自定义类用于forin、移除练习四种方案
4、反射(获得Class 三种方式、创建对象、读写属性、执行方法) *****
5、晚会案例  *****







































































































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值