Java包、类的加载机制(理论)

本人Java菜鸡一枚,如果下面的内容有误,请各位拼命留言,我秒秒钟改! 做项目的同时努力补全知识点或许是当务之急? 问题 此面试问题暴露了我对Java内部原理的无知,哈哈,赶紧学。题外话:换做面C++的话,我估计面试官会用一个多继承里头的问题来考。 有a.jar和b.jar,里面都有某个类MyClass且他们的包名完全相同,但是有不同的foo()方法,在一个项目中同时引入这两个jar会出现什么奇妙的事情呢? 这个问题的答案是,要根据类加载器的加载顺序来决定我们构建MyClass对象的时候究竟会先找到哪个jar里头的文件,a.jar/b.jar哪个运气好拔得头筹了,剩下的就被忽视了。 如果我们构建了不同的类加载器对象的话,可以通过自定义的类加载器来同时加载这两个长得看起来一模一样的类,并且可以各自调用其方法属性什么的。 更详尽的回答可以看这里:http://stackoverflow.com/questions/6879652/possible-to-use-two-java-classes-with-same-name-and-same-package 包(Package)、编译单元 C/C++里面用 #include来表示引用的类(文件),并且用过C++的盆友肯定知道 namespace 这个关键字可以用来隔离名字相同东西,最常见的莫过于 using namespace std; 了。以上这些与所谓“访问权限控制”有关(详见《Java编程思想》第6章)。 而Java以及诸如Python这种语言采用包(package)作为库单元,一个包内包含一组类,比如ArrayList在Java标准库中被放置在java.util包(名字空间)下。包的作用有点像地址,在寻找一个类的时候就像快递分拣一样,根据包的名字能找到最终的目标,一个不恰当的例子就是,package 浙江.杭州.西湖 底下可能会有 同仁医院 这个类,而 package 福建.福州.鼓楼(这个例子不恰当,因为按照Java的原意,包名应该是“从后往前”写的,如cn.com.ibm) 底下也可以有 同仁医院 这个类,在Java代码中使用类的内容的时候,Java虚拟机就得根据包的名称来确定你要引用的到底是哪个医院类了。 而所谓编译单元,大多是指Java源代码文件。一个编译单元的后缀就是.java,文件里只能有一个public的类且该类的名称与文件名相同,否则就会导致编译错误。Java解释器的运行过程大致是:找出环境变量CLASSPATH(包含一个或多个目录)用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换为反斜杠\,比如 浙江.杭州.西湖 就变成了目录 浙江\杭州\西湖(根据操作系统可能略有不同,变为正斜杠/也是有可能的)。随后解释器就在这么个目录中查找对应你给的类名称的.class文件,比如上面的 同仁医院.class。 编译执行流程 估计大家都知道,Java中的类可以被动态加载到Java虚拟机中执行。下面这张图(推荐https://www.processon.com/,在线画简单流程图的好东西)可以大致说明: Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance() 方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如 Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。 基本上所有的类加载器都是 java.lang.ClassLoader 类的一个实例。上图可以看出一点,就是通过不同的类加载器,可以加载出不同的Class类的实例。 java.lang.ClassLoader 之前说过类加载器是干啥使的,除了加载类以外,其实诸如图像文件什么的资源也是它加载的,不过这里暂且不谈。 java.lang.ClassLoader其实是一个抽象类,有几个比较重要的方法: getParent() 用于返回该类加载器的父类加载器;这个方法与经常能看到的“双亲委派”这个关键词有关:) loadClass(String name) 加载名称为name的类,返回java.lang.Class实例。 该方法有三步: 1.调用findLoadedClass方法看看是不是已经加载过这个类了; 2.如果没有,在父类加载器上调用loadClass方法。如果父类加载器是null(啊..到底了…),则用虚拟机的内置类加载器(下面讲到的引导类加载器); 3.还是不行,调用findClass方法查找类 findClass(String name) 查找名称为name的类,返回java.lang.Class实例 findLoadedClass(String name) 查找一个名为name的已经加载过的类,返回java.lang.Class实例 defineClass(String name, byte[] b, int off, int len) 把字节数组b中的内容转换为Java类,返回java.lang.Class实例,这是个final方法 resolveClass(Class<?> c) 链接指定的Java类 注意:里面的参数name都是二进制名称。
Continue reading Java包、类的加载机制(理论)

在SpringMVC 4 中用注释(Annotation)方式使用 Google Kaptcha (Captcha)

原创内容,转载请注明来自http://boweihe.me/?p=2026 近期在努力学习SpringMVC,因为之前对JSP也是一知半解的,干脆拿了本《Spring in Action》(4th edition)啃,发现使用注释的方式比用xml来的有意思一些。网站中要用到验证码,目前能找到的文档都是用xml配置的,感觉有点不爽,决定学我党“摸着石头过河”一次,希望不要naive了.. Maven库 Google自家的库估计是没了,大概是时间太久远了吧。我用的Maven库是这个

Bean配置文件 需要把原有的applicationContext.xml用注释的方式实现,其实就是让Spring找到个可以用的Bean并加载相关配置。   我构造了一个类来搞定这个事情,里面的配置参数会从application.properties文件中读取,我仅仅实现了我需要的几个参数,反正如果要加的话就在kaptchaProperties方法里面写就可以,然后Autowire一个Environment用来读取文件配置参数。主要是 @Configuration 注释,这个是告诉Spring我是个配置类,这个还是从Hibernate配置中学过来的,哈哈。 声明出来的这个 @Bean(name = "captchaProducer") 就是后面Controller里面要用的了

对应的application.properties,具体含义可以看参考文献里,解释的很清楚了。

CaptchaController 控制器 项目在实习前怕是赶不完来了,我还是少花点时间写博客吧。 控制器的实现Wiki上都有,主要的是要@Autowire之前我们做好的那个Bean,大概是这样。其实就是个基于set方法的注入嘛~

  参考文献: 在springmvc项目中使用kaptcha生成验证码 简单Maven的Web项目之验证码(Kaptcha篇) Spring mvc框架下使用kaptcha生成验证码 https://code.google.com/archive/p/kaptcha/wikis  

[Java]计算组合

基本功不扎实,写了半天写出来。 输入:一个长度n数组,比如{0,1,3,5},以及m 输出:组合CNM ===============

Java中HashMap遍历的两种方式

原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种:   

  效率高,以后一定要使用此种方式! 第二种:   

  效率低,以后尽量少使用! HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历,但两者的遍历速度是有差别的,下面请看实例:   public class HashMapTest {   public static void main(String[] args) …{   HashMap hashmap = new HashMap();   for (int i = 0; i < 1000; i ) …{   hashmap.put(“” i, “thanks”);   }   long bs = Calendar.getInstance().getTimeInMillis();   Iterator iterator = hashmap.keySet().iterator();   while (iterator.hasNext()) …{   System.out.print(hashmap.get(iterator.next()));   }   System.out.println();   System.out.println(Calendar.getInstance().getTimeInMillis() –
Continue reading Java中HashMap遍历的两种方式

Eclipse JRI : Java 调用 R 报错: Cannot find JRI native library!

Q: I get the following error, what’s wrong? java.lang.UnsatisfiedLinkError: no jri in java.library.path A: Usually it means that you didn’t setup the necessary environment variables properly or the JRI library is not where it is expected to be. The recommended way to start JRI programs is to use the run script which is generated along with the
Continue reading Eclipse JRI : Java 调用 R 报错: Cannot find JRI native library!