- 浏览: 295520 次
- 性别:
- 来自: 山东-东营-利津县
文章分类
- 全部博客 (155)
- J2SE (25)
- JavaScript (8)
- Linux (4)
- Struts (12)
- Mysql (8)
- Oracle (9)
- IT与生活 (12)
- EJB (7)
- JMS (1)
- Spring (5)
- Hibernate (6)
- Jsp&Servlet (4)
- 开发小技巧 (5)
- log4j (4)
- 面试题 (20)
- DWR (2)
- JBPM (1)
- iBATIS (4)
- 数据结构 (1)
- svn (1)
- 反编译 (1)
- DB2 (4)
- Tomcat (2)
- WebService (2)
- JBoss (5)
- jquery (1)
- HttpClient (1)
- jdom (1)
- mina (1)
最新评论
-
moment52:
为什么会选择用拦截器,不用action呢
使用ThreadLocal结合struts2的拦截器实现分页 -
wzk527:
很好
编程:编写一个截取字符串的函数,(网上流传的答案有的是错的)输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4 -
shijian2292:
lz辛苦了,写的真详细,我正郁闷这些问题呢,学习了。
struts2复习笔记(version2.1.6)(01~06) -
fgh2011:
如果想要在虚拟机之外的 局域网机器中访问应用 ip需要设置成自 ...
使用secureCRT连接用VMWare虚拟机装的Linux系统 -
wangljr:
...
什么是声明式事务?什么是编程式事务?
41、自定义泛型方法的练习与类型推断总结:
(6)类型参数的类型推断:太复杂不常用-->省略
42、自定义泛型类的应用:
public class Person {}
如果我们采用如上的方式定义方法,那么我们在调用的时候会出现如下情况:
public static void main(String[] args) {
GenericDao ge = new GenericDao();
ge.add(new Person());//我们添加的是Person类型
String s = ge.find(1);//而我们却可以以String类型的方式返回,编译器并不报错
}
但是我们在add的时候以T的类型传递过去的,返回的时候也是以T的类型返回的,那么为什么不行呢,因为这是两个方法,
你可以认为两个方法定义的T毫无关系。那么如何把T应用到这个类中的整个方法呢。我们应该把T定义到类名上就可以了
代码示例:
注意:当一个变量或方法被声明为泛型的时候,只能被实例变量和方法调用,而不能被静态变量
和静态方法调用。因为静态成员变量是被所有参数化的类的对象所共享的。如下:
示例代码:
对于Vector<Date> v1 如果只是根据v1这个对象,你是无法拿到Vector的参数化类型Date的,但是当这个类型的对象作为一个方法的参数的
时候,我们就可以利用反射的方式得到他了。
44、类加载器及其委托机制的深入分析
类加载器负责将 .class 文件(可能在磁盘上, 也可能在网络上) 加载到内存中, 并为之生成对应的 java.lang.Class 对象
当 JVM 启动时,会形成由三个类加载器组成的初始类加载器层次结构:
类加载器的树形结构
BootStrap 加载:JRE/lib/rt.jar
| |
| |
ExtClassLoader 加载:JRE/lib/ext/*.jar
| |
| |
AppClassLoader 加载:classpath指定的所有jar或目录
在AppClassLoader下面我们可以把我们自己写的ClassLoader挂载到下面用来装载我们的放在
特定目录的类。
(一、)当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
(1)首先当前线程的类加载器去加载线程中的第一个类。
(2)如果类A中引用了类B,Java虚拟机降使用加载类A的加载器来加载类B
(3)还可以直接调用ClassLoadedr.loadClass()方法来指定某个类加载器去加载某个类
(二、)每个类加载器加载文件的时候,都是先委托给其上级类加载器
(1)当所有的祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了
则抛出ClassNotFoundException,不是在去找发起者类加载器的儿子,因为没有
getChild方法,即使有,那有多个儿子找那一个呢?
(2)对类加载器的层次图和委托架子啊原理,解释先前将ClassLoaderTest输出成jre/lib/ext
目录下面的itcast.jar包后,运行结果为ExtClassLoader的原因?双亲委派机制
面试题:能不能自己写个类叫java.lang.String让泪加载器去加载他?
不能:为了不让我们写String类,类加载器采用委托机制,总是先让他的父类加载器
加载,这样总会加载到rt.jar所以总是使用java系统提供的String
示例代码:
ClassLoader是一个抽象类,里面有两个我们要写自己的类加载器将要用到的方法
//通过给他一个类名,来加载一个类返回这个类的字节码,这个方法内部在调用这个方法的时候会先
//找他的父加载器去加载,然会回来在去找findClass(String name)方法,如果你把这个方法覆盖了它加载的
//时候不会去找父类了,我们还要自己去写这段代码,所以我们用覆盖findClass(String name)方法就行了(保存流程)
(1)public Class<?> loadClass(String name):
//把一份字节数组转化为一个Class的一个实例对象
(2)protected final Class<?> defineClass(String name,byte[] b,int off, int len);
概念:模板方法的设计模式:
父类
子类1 子类2
许多相同的部分都放到父类中,而具体的细节由我们的子类自己完成自己的那部分,所以
重写父类的方法加入我们自己实现的细节就可以了。
46、编写对class文件进行加密的工具类
(1)编写加密工具类
第一个参数是你写的那个要加密的类生成的.class文件的路径
第二个参数是加密完成之后,生成的文件放到哪个文件夹下面
结果:在我们对ClassLoaderAttachment.toString()进行打印的时候,会输出hello world 因为这个时候他的.class文件没有加密,当我们用家完密
的.class文件覆盖它的.class文件 然后再运行就出错了。
47、编写和测试自己编写的解密类加载器
在上一个示例中,我们对类的.class文件进行了加密,所以无法运行,在这个例子中我们进行解密操作;
在MyClassLoader 继承 ClassLoader并重写他的findClass(String name) 方法:
//添加二个构造方法和一个属性用于传递.class文件名
(1)编写一个方法自动将Object类型转化为其他的类型 代码示例: public static <T>T autoConvert(Object obj) { return (T)obj; } (2)将任意类型数组中的每一个元素填充为任意类型的对象。 代码示例: public static <T>void fillArray(T[] a, T obj) { for(int i=0; i<a.length; i++) { a[i] = obj; } } (3)采用自定义泛型的方法打印出任意参数化集合类型中的内容: 代码示例: //采用通配符 public static void printCollection(Collection<?> coll) { for(Object obj : coll) { System.out.println(obj); } //错误:因为无法知道?到底是什么类型,你add一个String类型,万一?是Integer呢? //coll.add("abc"); } //采用泛型 public static <T>void printCollection2(Collection<T> coll, T obj2) { for(Object obj : coll) { System.out.println(obj); } coll.add(obj2); } (4)把任意参数化类型的数组中的数据安全的复制到相应类型的集合中 代码示例: public static <T>void copyCollection1(Collection<T> dist, T[] src) { for(int i=0; i<src.length; i++) { dist.add(src[i]); } } (5)把任意参数类型的数组中的数据安全的复制到另外一个数组中: 代码示例: public static <T>void copyCollection2(T[] dist, T[] src) { } 调用: public static void main(String[] args) { //T表示的都是String copyCollection1(new Vector<String>(), new String[20]); //取交集:Object copyCollection2(new Date[10], new String[10]); //错误:new Vector<Date>已经指定了T:Date 而后面又new String:这是不可以的 //这叫做泛型的传播性 //copyCollection1(new Vector<Date>(), new String[20]); }
(6)类型参数的类型推断:太复杂不常用-->省略
42、自定义泛型类的应用:
代码示例: /** * 自定义泛型模仿Dao层的crud * @author Administrator * */ public class GenericDao { public <T>void add(T obj) { } public <T>T find(int id) { return null; } }//定义测试用类:
public class Person {}
如果我们采用如上的方式定义方法,那么我们在调用的时候会出现如下情况:
public static void main(String[] args) {
GenericDao ge = new GenericDao();
ge.add(new Person());//我们添加的是Person类型
String s = ge.find(1);//而我们却可以以String类型的方式返回,编译器并不报错
}
但是我们在add的时候以T的类型传递过去的,返回的时候也是以T的类型返回的,那么为什么不行呢,因为这是两个方法,
你可以认为两个方法定义的T毫无关系。那么如何把T应用到这个类中的整个方法呢。我们应该把T定义到类名上就可以了
代码示例:
public class GenericDao<T> { public void add(T obj) { } public T find(int id) { return null; } }如果这样定义,我们就能保证添加进去的和拿出来的是同一类的对象。
注意:当一个变量或方法被声明为泛型的时候,只能被实例变量和方法调用,而不能被静态变量
和静态方法调用。因为静态成员变量是被所有参数化的类的对象所共享的。如下:
public class GenericDao<T> { //报错: public static void update(T obj) { } 应改为: public static void update(T obj) { } }43、通过反射获得泛型实际类型参数:
示例代码:
public static void main(String[] args) { //得到方法applyVector的反射对象 Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class); //得到这个方法的"泛型的参数化类型"返回一个数组,因为这个方法可能有多个参数 Type[] types = applyMethod.getGenericParameterTypes(); //因为我们知道我们的方法中只有一个参数所以:types[0] ParameterizedType pType =(ParameterizedType) types[0]; //得到第一参数的真实类型:Vector System.out.println(pType.getRawType()); //.getActualTypeArguments():得到第一个参数的参数化类型(可以简单理解为:就是泛型),是一个数组,因为可能有多个例如:Map<K,V> System.out.println(pType.getActualTypeArguments()[0]); } public static void applyVector(Vector<Date> v1) { }
对于Vector<Date> v1 如果只是根据v1这个对象,你是无法拿到Vector的参数化类型Date的,但是当这个类型的对象作为一个方法的参数的
时候,我们就可以利用反射的方式得到他了。
44、类加载器及其委托机制的深入分析
类加载器负责将 .class 文件(可能在磁盘上, 也可能在网络上) 加载到内存中, 并为之生成对应的 java.lang.Class 对象
当 JVM 启动时,会形成由三个类加载器组成的初始类加载器层次结构:
类加载器的树形结构
BootStrap 加载:JRE/lib/rt.jar
| |
| |
ExtClassLoader 加载:JRE/lib/ext/*.jar
| |
| |
AppClassLoader 加载:classpath指定的所有jar或目录
在AppClassLoader下面我们可以把我们自己写的ClassLoader挂载到下面用来装载我们的放在
特定目录的类。
(一、)当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
(1)首先当前线程的类加载器去加载线程中的第一个类。
(2)如果类A中引用了类B,Java虚拟机降使用加载类A的加载器来加载类B
(3)还可以直接调用ClassLoadedr.loadClass()方法来指定某个类加载器去加载某个类
(二、)每个类加载器加载文件的时候,都是先委托给其上级类加载器
(1)当所有的祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了
则抛出ClassNotFoundException,不是在去找发起者类加载器的儿子,因为没有
getChild方法,即使有,那有多个儿子找那一个呢?
(2)对类加载器的层次图和委托架子啊原理,解释先前将ClassLoaderTest输出成jre/lib/ext
目录下面的itcast.jar包后,运行结果为ExtClassLoader的原因?双亲委派机制
面试题:能不能自己写个类叫java.lang.String让泪加载器去加载他?
不能:为了不让我们写String类,类加载器采用委托机制,总是先让他的父类加载器
加载,这样总会加载到rt.jar所以总是使用java系统提供的String
示例代码:
public class ClassLoaderTest { public static void main(String[] args) { //AppClassLoader System.out.println( ClassLoaderTest.class.getClassLoader().getClass() .getName() ); //报错:getClassLoader()拿到的是null因为System类由BootStrap类加载器加载,而这个加载器我们是拿不到的 //是嵌在JVM中的, System.out.println( System.class.getClassLoader().getClass() .getName() ); ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); //输出所有的类加载器 while(classLoader != null) { System.out.println(classLoader); //拿到它的父类加载器 classLoader = classLoader.getParent(); } System.out.println(classLoader); //输入结果:AppClassLoader、ExtClassLoader、null null是因为我们拿不到了,实际上是BootStrap } }45、自定义类的加载器的编写原理分析:
ClassLoader是一个抽象类,里面有两个我们要写自己的类加载器将要用到的方法
//通过给他一个类名,来加载一个类返回这个类的字节码,这个方法内部在调用这个方法的时候会先
//找他的父加载器去加载,然会回来在去找findClass(String name)方法,如果你把这个方法覆盖了它加载的
//时候不会去找父类了,我们还要自己去写这段代码,所以我们用覆盖findClass(String name)方法就行了(保存流程)
(1)public Class<?> loadClass(String name):
//把一份字节数组转化为一个Class的一个实例对象
(2)protected final Class<?> defineClass(String name,byte[] b,int off, int len);
概念:模板方法的设计模式:
父类
子类1 子类2
许多相同的部分都放到父类中,而具体的细节由我们的子类自己完成自己的那部分,所以
重写父类的方法加入我们自己实现的细节就可以了。
46、编写对class文件进行加密的工具类
(1)编写加密工具类
public class MyClassLoader { public static void main(String[] args) throws Exception { String srcPath = args[0]; //D:\J2SE\EclipseWorkSpace\javaenhance\bin\cn\itcast\day2\ClassLoaderAttachment.class String destDir = args[1]; //itcast String destFileName = srcPath.substring(srcPath.lastIndexOf('\\') + 1); //ClassLoaderAttachment.class String destPath = destDir + "\\" + destFileName; //itcast\ClassLoaderAttachment.class FileInputStream fis = new FileInputStream(srcPath); FileOutputStream fos = new FileOutputStream(destPath); cyper(fis, fos ); } public static void cyper(InputStream ips, OutputStream ops) throws Exception { int b = -1; while((b =ips.read())!= -1) { ops.write(b ^ 0xff); } } } (2)生成.class文件的测试类 public class ClassLoaderAttachment extends Date { @Override public String toString() { return "hello world"; } } (3)运行测试 //出错: System.out.println(new ClassLoaderAttachment().toString());Run as --->args参数:D:\J2SE\EclipseWorkSpace\javaenhance\bin\cn\itcast\day2\ClassLoaderAttachment.class itcast
第一个参数是你写的那个要加密的类生成的.class文件的路径
第二个参数是加密完成之后,生成的文件放到哪个文件夹下面
结果:在我们对ClassLoaderAttachment.toString()进行打印的时候,会输出hello world 因为这个时候他的.class文件没有加密,当我们用家完密
的.class文件覆盖它的.class文件 然后再运行就出错了。
47、编写和测试自己编写的解密类加载器
在上一个示例中,我们对类的.class文件进行了加密,所以无法运行,在这个例子中我们进行解密操作;
在MyClassLoader 继承 ClassLoader并重写他的findClass(String name) 方法:
//添加二个构造方法和一个属性用于传递.class文件名
public MyClassLoader() { } private String fileDir; public String getFileDir() { return fileDir; } public void setFileDir(String fileDir) { this.fileDir = fileDir; } public MyClassLoader(String fileDir) { this.fileDir = fileDir; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { //找到那个错误的.class文件的位置 String filePath = fileDir + '\\' + name + ".class"; FileInputStream fis; try { fis =new FileInputStream(filePath); ByteArrayOutputStream baos = new ByteArrayOutputStream(); //解密 cyper(fis, baos); fis.close(); byte[] bytes = baos.toByteArray(); baos.close(); //解密完成之后调用defineClass方法返回一个Class对象 Class clazz = defineClass(bytes, 0, bytes.length); return clazz; } catch (Exception e) { e.printStackTrace(); } return super.findClass(name); } 测试运行: Class clazz = new MyClassLoader("itcastlib").findClass("ClassLoaderAttachment"); //这个地方不呢个直接写: ClassLoaderAttachment d1 = (ClassLoaderAttachment)clazz.newInstance(); //因为如果这样写,因为用到了ClassLoaderAttachment这个类ClassLoader会又去加载这个类的字节码这个时候还没有解密所以会报错 //所以先写他的父类 Date d1 = (Date)clazz.newInstance(); System.out.println(d1.toString());
发表评论
-
关于java读取properties文件的路径问题
2013-02-02 23:57 13141之前对于JAVA读取propertie ... -
StringBuffer与StringBuilder的区别
2012-07-23 16:08 0相信大家看到过很多比较String和StringBuffer区 ... -
java中Date与String的相互转化 (转)
2012-07-23 15:35 1285import java.text.DateFormat; ... -
使用eclipse fat插件制作可运行jar
2012-06-05 13:59 0转载自http://blog.csdn.net/jikeyzh ... -
使用eclipse fat插件制作可运行jar
2012-06-05 13:59 1089转载自http://blog.csdn.net/jikeyzh ... -
关于JAVA类中各个成分的初始化顺序(转载)
2012-04-28 23:30 833... -
关于J2SE一些细节问题的整理(如有错误,欢迎留言指正)
2011-10-23 16:03 10531、关于继承中private的 ... -
Java heap space[转]
2011-09-13 14:17 801PermGen space的全称是Permanent Gene ... -
super关键字与内存分布
2010-05-13 21:19 1204当我们new出一个子类对象的时候,这个子类对象内部肯定会包含一 ... -
继承中的构造方法
2010-05-13 21:12 10391、子类的构造过程中必须调用其基类的构造方法。 2、子类在自 ... -
关于方法的重载
2010-05-12 16:41 852public class Person { publ ... -
成员变量和局部变量的一点不同
2010-05-12 12:25 903在java中,如果你在class中定义了一个成员变量然 ... -
环境变量中的系统环境变量和用户环境变量有什么区别?
2010-05-10 21:31 2855系统环境变量的意思是无论你是用那个用户帐号登陆后都能够共 ... -
final关键字到底修饰了什么
2010-05-05 22:55 1056final使得被修饰的变量"不变",但是由 ... -
synchronized 的语法:(转载)
2010-04-15 21:53 1209synchronized 的语法: synchronize ... -
System.getProperty(String name)的常用值总结(转载)
2010-03-29 15:41 1055常用的System.getProperty(),这里贴一下,省 ... -
各种进制之间的转换(转载)
2010-03-24 11:59 1885各种进制转换 计算机中常用的数的进制主要有:二进制、八进制、十 ... -
Class.forName(String name)的作用(转载)
2010-03-22 23:08 1311Class.forName(xxx.xx.xx) 返回的是一个 ... -
ClassLoader的加载机制相关
2010-03-22 23:05 998面试题:能不能自己写个类叫java.lang.String让泪 ... -
张孝祥J2SE加强自学笔记(48-56)
2010-03-22 22:49 168848、类加载器的一个高级问题的实验分析: 这次我们新建一个w ...
相关推荐
【张孝祥J2SE加强自学笔记(48-56)】主要涵盖了类加载器、代理类和动态类创建等Java核心知识点。 48、类加载器的问题实验分析: 在Java中,类加载器是负责查找并加载类的机制。在Web应用中,有多种类加载器,如...
3. 多态(Polymorphism):多态是指同一个接口可以有不同的实现方式,即子类可以重写父类的方法,使得相同的操作可以作用于不同的对象,增强了代码的灵活性。Java中的方法重写(Override)和接口实现是多态的重要...
详细解释了html语言、css、javascript语法、dom对象编程、正则表达式,介绍了网页脚本编程的其他技术和知识。(由于上传限制,故将本教程分为6个部分上传,请全部下载后解压)
【张孝祥_高级j2se代码】这个资源包含了张孝祥老师精心编写的J2SE(Java 2 Standard Edition)高级代码示例,旨在帮助开发者深入理解和掌握Java核心技术。J2SE是Java平台的核心部分,它提供了丰富的类库和API,支持...
张孝祥课程学习笔记,包括JAVA基础,JAVA高级,JavaScript全部的笔记,适合初学者。
ed2k://|file|[张孝祥JAVA视频教程!(1-5课)].lesson01.[XiDong.Net].rmvb|555980477|1954514FA6C5757740064027D85826C1|h=EDKWEPSDDPS42DLGMONDGZPTQ7VF5BWX|/ ………………省略部分………… 第二部分 ed2k://|...
详细解释了html语言、css、javascript语法、dom对象编程、正则表达式,介绍了网页脚本不编程的其他技术和知识。(由于上传限制,故将本教程分为6个部分上传,请全部下载后解压)
详细解释了html语言、css、javascript语法、dom对象编程、正则表达式,介绍了网页脚本编程的其他技术和知识。(由于上传限制,故将本教程分为6个部分上传,请全部下载后解压)
张孝祥Java邮件开发详解-高清扫描版-part1 绝对是精品 张孝祥的好书 。很大,分为2部分。
j2se基础加强_张孝祥版ppt,对于java的基础提升是很有帮助的。
传智播客-------张孝祥老师--------------- javaMail开发PPT
【Java基础加强】张孝祥的Java教学视频涵盖了Java编程语言的基础到进阶知识,旨在帮助学习者巩固和提升Java编程技能。以下是根据教程笔记整理的一些关键知识点: 1. **Java简介**:Java是一种跨平台的面向对象的...
张孝祥Java邮件开发详解-高清扫描版-part2
Java基础加强--张孝祥版 传智播客
jAVA基础+高新+7K知识点总结.chm 需要的可以下载
### 张孝祥Java多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...
### 张孝祥老师讲课笔记:深入理解Windows程序运行机制 #### Windows程序设计与传统DOS方式的区别 张孝祥老师的讲课笔记强调了Windows程序设计与传统的DOS方式有着本质的不同,尤其体现在程序运行机制上。Windows...
张孝祥交通灯管理系统笔记 面试题视频教程笔记
张孝祥Java多线程与并发库高级应用学习笔记,很经典的学习多线程和并发的资料。张孝祥Java多线程讲义笔记由张孝祥亲自整理,很实用的。