关于JSP中的pageContext:
使用pageContext所设定的属性对象,其共享范围限于同一个JSP页面,
使用request所设定的属性对象,其在同一个request处理期间可以共享(包括forward给其它JSP页面),
session对象所设定的属性对象则限于同一个进程作用期间可以共享,
而application对象所设定的属性,则在整个Web应用程序中的JSP页面都可以共享。
Final的初始化
1. final修饰的成员变量没有默认值
2. final初始化可以在三个地方
(1)声明的时候初始化
(2)构造函数里初始化
(3)要是没有static修饰的话可以在非静态块里初始化,要是有static修饰的话可以在静态块里初始化
3. 使用final成员前要确保已经初始化,如果没初始化,或者初始化多次,则无法通过编译。
一些转换技巧
- Map<String, HandlerMapping> matchingBeans =
- BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
-
- //map转换list
- List<HandlerMapping> handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
-
- //map判断空
- if (!matchingBeans.isEmpty())
-
- //数组转List (interceptors 数组)
- interceptorList.addAll(Arrays.asList(this.interceptors));
-
- //List转指定对象数组
- interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
java.lang.Number是所有基础类型的父类
- public abstract class Number implements java.io.Serializable {
-
- public abstract int intValue();
-
- public abstract long longValue();
-
- public abstract float floatValue();
-
- public abstract double doubleValue();
-
- public byte byteValue() {
- return (byte)intValue();
- }
-
- public short shortValue() {
- return (short)intValue();
- }
- }
- public final class Long extends Number implements Comparable<Long>
-
- public final class Integer extends Number implements Comparable<Integer>
JDK、JRE、JVM
JDK:Java Development ToolKit
Java开发工具包
JRE:Java Runtime Environment
Java运行环境
JVM:Java Virtual Machine
Java虚拟机
JMM:Java Memory Model
Java内存模型
JDK是SUN公司发布的用于开发Java程序的工具包
在它的bin目录下有很多工具,常见的包括:javac.exe,java.exe,javadoc.exe等(其中有很多都是用Java编写的)各种版本的IDE工具也是需要使用JDK来完成编译,打包,运行等各种功能的。
JRE顾名思义,java的运行环境
JDK是开发工具,在它的安装目录下包含了JRE目录,其实在安装JDK时(1.4版本以上),有一个安装选项,如果勾上时,在Java的安装目录下会多一个JRE目录,这里的JRE与JDK下的JRE目录基本上是完全一致的,那么为什么需要两个JRE呢?
前面已经提到过,JDK的bin目录下的很多工具都是用Java编写的,使用这些工具的时候也是需要运行环境的,通过这些.exe包装器(这些包装器提供了寻找tools.jar中的一些java类的快捷方法,不需要输入一长串的包名和类名)来使用那些工具时,java会自动寻找父目录下的JRE,所以在这里放置了JRE。
JVM:Java虚拟机,在window下作为动态连接库(jvm.dll)存在,用于解释执行Java字节码。jvm.dll文件路径为:jre7\bin\server
可以把它理解成是专门用来执行Java程序的一台机器。也就是说JVM提供了Java执行的硬件平台。JVM上执行的代码都存放在.CLASS文件中。JVM只执行字节码文件。
==================================================================
Java的跨平台如何体现:
JVM也是一个软件,不同的平台有不同的版本。我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码然后运行。也就是说,只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。
注意:编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。
所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。
注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,不能跨平台,不同平台下需要安装不同版本的JVM。
finalize()
Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。
finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
垃圾收集器只知道释放那些由new分配的内存,所以不知道如何释放对象的“特殊”内存。为解决这个问题
Java提供了一个名为finalize()的方法,它的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。
所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作(如关闭流等操作)。但JVM(Java虚拟机)不保证此方法总被调用。
原子操作AtomicInteger
- public class AtomicLong extends Number
- implements Serializable
不使用synchronized关键字,AtomicInteger通过另一种线程安全的方法实现加减操作。
AtomicInteger为什么能够达到多而不乱,处理高并发应付自如呢?
这是由硬件提供原子操作指令实现的,这里面用到了一种并发技术:CAS。在非激烈竞争的情况下,开销更小,速度更快。
Java.util.concurrent中实现的原子操作类包括:
AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicReference、AtomicReferenceArray。
J2SE 5.0提供了一组atomic class来帮助我们简化同步处理。
基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增、减、赋值(更新)操作. 比如对于++运算符, AtomicInteger可以将它持有的integer 能够atomic 地递增。在需要访问两个或两个以上 atomic变量的程序代码(或者是对单一的atomic变量执行两个或两个以上的操作)通常都需要被synchronize以便两者的操作能够被当作是一个atomic的单元。
- addAndGet(long delta)
- //以原子方式将给定值添加到当前值。
-
- getAndSet() :
- //设置新值,返回旧值.
-
- compareAndSet(expectedValue, newValue) :
- //如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值
- //如果更新成功,返回true, 否则返回false
- //换句话可以这样说: 将原子变量设置为新的值, 但是如果从我上次看到的这个变量之后到现在被其他线程修改了(和我期望看到的值不符), 那么更新失败
- /* 单线程下, compareAndSet返回永远为true,
- * 多线程下, 在与result进行compare时, counter可能被其他线程set了新值, 这时需要重新再取一遍再比较,
- * 如果还是没有拿到最新的值, 则一直循环下去, 直到拿到最新的那个值
- */
-
- int incrementAndGet()
- 以原子方式将当前值加 1。
为了提高性能,AtomicLong等类在实现同步时,没有用synchronized关键字,而是直接使用了最低层(本地c语言实现代码)来完成的,
因而你是看不到用synchronized关键字的.
比如:AtomicLong类中原子操作方法:
public final boolean compareAndSet(long expect, long update) ;
就是直接使用SUN公司低层本地代码的原子方法(native方法):
public final native boolean compareAndSwapLong(...)来实现的.
Example:
- import java.util.*;
- import java.util.concurrent.*;
- import java.util.concurrent.atomic.*;
- /*
- * ava.util.concurrent中实现的原子操作类包括:
- AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicReference、
- AtomicReferenceArray。
- *
- */
- public class AtomicOperationDemo {
- static AtomicInteger count=new AtomicInteger(0);
- public static class AddThread implements Runnable{
- @Override
- public void run() {
- for(int k=0;k<1000;k++){
- count.incrementAndGet();
- }
- }
- }
-
-
- public static void AtomicIntShow(){
- System.out.println("AtomicIntShow() enter");
- ExecutorService threadpool = Executors.newFixedThreadPool(10);
-
- //开100个线程
- for(int k=0;k<100;k++){
- threadpool.submit(new AddThread());
- }
-
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- /* output
- * AtomicIntShow() enter
- * result of acumulated sum=100000
- * AtomicIntShow() exit
- */
-
- System.out.println("result of acumulated sum="+count);
- threadpool.shutdown();
- System.out.println("AtomicIntShow() exit");
- return ;
-
- }
- }
-
-
- public class Maintest {
- public static void main(String[] args) {
- AtomicOperationDemo.AtomicIntShow();
- }
- }
-
-
- 结果:
- /* output
- * AtomicIntShow() enter
- * result of acumulated sum=100000
- * AtomicIntShow() exit
- */
Object、String类中equals方法的不同
StringBuffer / StringBuilder的equals方法都是继承的Object方法
String类中对equals方法进行了重写
Object类的equals方法的实现:
- public boolean equals(Object obj) {
- return (this == obj);
- }