JDK1.5的新特性 04
来源:互联网 发布:手机无法安装软件 编辑:程序博客网 时间:2024/06/03 09:33
一,泛型
A.泛型的由来:强转的麻烦,非法类型的输入,运行后再修改的费事;
B.泛型的原理:a.编译时期,编译器按照泛型限定的类型对程序员输入的元素类型进行鉴定,
类型超出限定的范围就报;
b.如何证明泛型只作用于编译器?通过反射得到的集合,可以装入任意对象;
C.需求的扩展:限定范围多元化
a.单种类型:<String>
b.多种类型:<? extends Person> <? super Student> <? extends Person && super Student>
C.任意类型:<?><E><T>
D.泛型的应用:自定义泛型
a.自定义方法泛型
b.自定义类泛型
二,类加载器
A.默认加载方法:委托加载机制
B.委托加载机制的意义:越基础的类(系统类),越不能被覆盖,所以rt.jar优先,ext.jar其次,相对路径最后;
C.自定义加载器的创建:
D.加载器、I/O流、位运算的综合运用:class文件加密和解密;
E.自定义加载器的典例:
a.Tomcat服务器
b.MyServlet.class文件
c.WebappClassLoader加载器
F.自定义加载器的应用问题:必须把父类class文件与子类class文件放到同一目录下;
笔记:
36,入门泛型的基本应用
需求:
1,在向集合添加元素时,加人了非目的对象,却没人提醒,到运行后出错了才发现问题!
然后回来把不符合条件的对象删除,事后处理,麻烦又耗时,影响工作效率,能不能给集合做些注释,
让编译器帮忙监督,以确保添加的元素都符合要求?
2,在定义比较器时,类型转换好麻烦,有没有更好的办法?
技术:泛型-指定类型:在定义集合时,给集合进行元素类型限定即可,同理,在定义类,定义方法时,都可以限定类型;
让类型转换好麻烦! int i = (Integer)collection1.get(1);
有问题:执行的时候抛异常!1角标上的集合元素类型不是Integer!!
37,泛型的内部原理及更深应用
原理和应用
提问:如何证明泛型是给编译器看的,而不是给虚拟机看的?
编译时期有作用,运行时期没作用,反射可以直接获取字节码文件,不经过编译,可以向结合添加任意对象;
总结:
定义泛型是给编译器看的,通过反射,可以添加元素,也可以获取元素,不受类型限制。
泛型参数,不考虑继承关系,声明和事例要一致;
思考:
Vector v1 = new Vector<String>();//对吗?对的
Vector<Object> v2 = v1;//对吗?对的 编译是对的,运行是错的。
38,泛型的通配符扩展应用
需求扩展:
1,某种类型:没有通配符 <String>
2,多种类型:不是只允许String类,而且允许其子类!<?extends Person> / <? super Person> /
如:HashMap(Map<? extends k,? extends v> m)
3,区间类型:是某个类的子类,但又是某个类的父类 <? extends XXX & super YYY >
4,所有类型:<?> <T>
39,泛型集合的综合应用案例
需求:如何对其元素进行迭代?
分析:与List和Set不同,Map集合是成对存储的,所以迭代器不适用,要对元素进行获取,
需要对外提供键和值的获取方法方法(键作为映射,不需要修改;);
思路:既然Map没有继承Iterable接口,那么就应该建立一个内部接口继承Iterable接口
办法:Map子类的内部类Entry:Map.Entry
对自己的能力要有明确要求:1,通过API了解新技术,应用新技术;
2,通过eclipse验证、应用、学习新技术;
3,通过eclipse方便高效地编写程序;
40,自定义泛型方法及其应用
用别人的,做自己的出来给别人用。
<T extends 接口&接口>
41,自定义泛型的练习与类型推断总结
需求:方法需要参数,参数需要类型指定和声明
42,自定义泛型类的应用
需求:类也需要泛型指定
对象:dao crud增添改成
dao
43,通过反射活得泛型的实际类型参数
需求:我想知道获得每个类的某个方法的泛型类型
思路:通过字节码和方法名,获得方法对象,
Method applyMethod = GenericTest.class.getMethod("applyVector",Vector.class);
再通过方法对象获取泛型类型;
Type[] types = applyMethod.getGenericParameterTypes();
总结:代码的封装与组合;以函数、类、包为封装体,以嵌套链接为组合;
44,类加载器及其委托机制的深入分析
需求:从硬盘到内存,从文件到字节码;如何将class文件加载到内存中?
分析:不同的class文件,存在不同级别的目录中,不同的目录由不同的加载器负责加载。
成果:1,BootStrap 爷爷优先加载的是最基础的类(如System类)的class文件——JRE/lib/rt.jar
2,ExtClassLoader父亲加载基本的类的class文件 ——JRE/lib/ext/*.jar
3,AppClassLoader儿子加载的是自定义类的class文件 ——classpath目录下的类文件
BootStrap,Strap:带,绑定;虚拟机内核自带;
Ext:abbr. 提取(extract);扩展(extension)
AppClassLoader,App,应用的意思;也就是我们开发的类是应用层的类;
ClassLoaderTest.java
默认的三个加载器:己、父、爷
委托加载机制,顶级优先管理模式;
思考:为什么要不类放到不同目录的jar包中?
回答:为了分等级,以确保类的优先级,避免重要的基础类被应用类替换(系统优先,扩展其次,自定义最后)
45,自定义类加载器的编写原理分析
需求:处于安全考虑,对class文件进行加密处理,加载class文件时进行解密,可是默认加载方法(加载委托机制)是没有
解密功能的,能否建立自定义的加载器?
分析:为了满足个性化的需求,一定有默认加载方式和自定义加载方式,有个描述类加载器的类(ClassLoader),要建立自定义
的功能,往往要继承类并复写对应方法;
技术:模版方法设计模式
ClassLoader
loadClass()
覆盖findClass 调用defineClass:
public Class findClass(String name){
//把字节码数据下载到数组中
byte[] b = loadClassData(name);
//把类名,数组,数组的0角标开始获取n个元素,n为数组长度。
return defineClass(name,b,0,b.length);
}
46,编写对class文件加密的工具类
需求:对class文件加密
分析:要产生一个加密的文件,必须用到IO流技术和异或运算;
理解:异或技术,两次异或可以把数据还原;
|0101 0001|
|0001 1010| 异或:相同为假,不同为真;
|0100 1011| 结果
|0001 1010| 再异或一次
|0101 0001|
现象:与0不变,与1必变;
理论:0&0为0;1&0为1;
0&1为1;1&1为0;
结论:数据变化在1对应位;
口诀:与1必变,再与再变终还原;
//加密功能
public static void cypher(InputStream ips,OutputStream ops) throws Exception{
int data = -1;
while ((data=ips.read())!=-1) {
ops.write(data^0xee);
}
}
47,编写和测试自己编写的解密类加载器
分析:1,密码:class文件加密和解密,必须是同一个异或运算,所以把异或方法定义在加载器类中;
2,加载:类的加载其实也是流的体现,自定义一个类加载器(MyClassLoader),加载时,调用异或方法(cypher()),
对流中的数据进行解密;
让加载器起作用: 删除父加载器对应的目录下的class文件,让虚拟机通过自定义加载器加载class文件,
然后重启虚拟机,(重启是必须的)
排除问题的小技巧:window ——show view —— proplems
//打破委托记载机制
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 获取class文件,需要路径,需要解码
String classfilename = classDir + "\\"+name + ".class";
try {
//建立流,用相印的异或方法进行解密;
FileInputStream fis = new FileInputStream(classfilename);
ByteArrayOutputStream bos = new ByteArrayOutputStream();//数组输出流没有目的,只在内存;
cypher(fis, bos);
fis.close();
byte[] bytes = bos.toByteArray();
return defineClass(bytes,0, bytes.length);
} catch (Exception e) {
System.out.println(e);
}
return super.findClass(name);
}
48,类加载器的一个高级问题的实验分析
指引:有一个类,是用自己的类加载器加载的;那就是Tomcat服务器,MyServlet.class文件,WebappClassLoader;
描述:public class MyServlet extends HttpServlet{} 即,MyServlet继承了HttpServlet;全部由WebappClassLoader加载;
问题:当把MyServlet.class文件放到ext目录下后,报错。
思考:一定是加载器找不到class文件,ExtClassLoader在ext下找到了MyServlet.class文件文件;掌握了加载器权,
其必须亲子加载父类类文件,可惜在自己的管辖范围内找不到父类HttpServelet.class
结论:1,规则:加载器一旦加载了一个类的类文件,及必须加载该类的父类类文件——负责到底!
2,措施:把HttpServelet.class也放到ext目录下;——把父类和子类的lass文件放在同一目录下;
- JDK1.5的新特性 04
- JDK1.5-JDK1.8的新特性
- jdk1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- jdk1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- jdk1.5的新特性
- jdk1.5的新特性
- jdk1.5的新特性
- JDK1.5的新特性
- JDK1.5的新特性
- JDK1.5,JDK1.6,JDK1.7 各自的新特性
- JDK1.5 新特性
- 翻转句子中单词的顺序[算法]
- JDK1.5的新特性 03
- 进程各个不同数据段的位置
- 求1+2+...+n[C/C++/C#]
- 链表中倒数第k个结点
- JDK1.5的新特性 04
- wangzhi
- JS中的类
- 求二元查找树的镜像
- Linux mint 13 ---- Dictionary 配置
- 从上往下遍历二元树
- 最短路径与Dijkstra算法
- eclipse+tomcat测试连接时候HTTP Status 404错误
- 网站采集防范