框架源码学习笔记
2016-03-07 22:18
561 查看
1.@WebListener
Servlet3.0提供@WebListener注解将一个实现了特定监听器接口的类定义为监听器,这样我们在web应用中使用监听器时,也不再需要在web.xml文件中配置监听器的相关描述信息了。
Web应用启动时就会初始化这个监听器
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContex销毁");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContex初始化");
System.out.println(sce.getServletContext().getServerInfo());
}
}
参考:Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
2.ServletRegistration
只能在webapp启动在初始化时进行完成注册,可能是为了安全考虑吧.
在Servlet3.0中可以动态注册Servlet,Filter,Listener
servlet 3.0笔记之servlet的动态注册
第十六章_动态注册和Servlet容器初始化
3.setAccessible(true)
Method actionMethod
actionMethod.setAccessible(true); // 取消类型安全检测(可提高反射性能)
4.instanceof
instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
java中instanceof用法
下面是调用Spring的函数
注意:getClass返回的是Class类型
这里也可以用if(args[0].getClass().getName().contains("com.xxx"))来判断是否指定类,但是没用instanceof直观
5.判断Map是否为空
6.Map.Entry
视图操作 :处理映像中键/值对组
Set keySet(): 返回映像中所有关键字的视图集
“因为映射中键的集合必须是唯一的,您用Set支持。你还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是你不能添加任何元素。”
Collection values():返回映像中所有值的视图集
“因为映射中值的集合不是唯一的,您用Collection支持。你还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是你不能添加任何元素。”
Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对
“因为映射是唯一的,您用Set支持。你还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是你不能添加任何元素。”
Map.Entry接口
Map的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。
通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。当条目通过迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。
(1) Object getKey(): 返回条目的关键字
(2) Object getValue(): 返回条目的值
(3) Object setValue(Object value): 将相关映像中的值改为value,并且返回旧值
7.getRequestDispatcher()与sendRedirect()的区别
1.request.getRequestDispatcher()是请求转发,前后页面共享一个request ;
response.sendRedirect()是重新定向,前后页面不是一个request。
request.getRequestDispather();返回的是一个RequestDispatcher对象。
2.RequestDispatcher.forward()是在服务器端运行;
8.引用JSTL
The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
http://blog.csdn.net/lzz313/article/details/7554736 http://blog.sina.com.cn/s/blog_7ffb8dd501013fvl.html
9.ThreadLocal
每个线程相互独立了,同样是 static 变量,对于不同的线程而言,它没有被共享,而是每个线程各一份,这样也就保证了线程安全。 也就是说,TheadLocal 为每一个线程提供了一个独立的副本!
ThreadLocal 的 API,其实很简单
public void set(T value):将值放入线程局部变量中
public T get():从线程局部变量中获取值
public void remove():从线程局部变量中移除值(有助于 JVM 垃圾回收)
protected T initialValue():返回线程局部变量中的初始值(默认为 null)
为什么 initialValue() 方法是 protected 的呢?就是为了提醒程序员们,这个方法是要你们来实现的,请给这个线程局部变量一个初始值吧。
ThreadLocal 具体有哪些使用案例呢:通过 ThreadLocal 存放 JDBC Connection,以达到事务控制的能力。
当您在一个类中使用了 static 成员变量的时候,一定要多问问自己,这个 static 成员变量需要考虑“线程安全”吗?
也就是说,多个线程需要独享自己的 static 成员变量吗?如果需要考虑,那就请用 ThreadLocal 吧!
参考: ThreadLocal 那点事儿
10.return this
return this 返回的是当前方法所在的类的实例,例如 StringBuilder 中的 append,这样做的好处就是可以 append("XXX").append("XXX").append("XXX")....
这样连续调用同一个方法。
参考:初学Java,方法中返回this,连续调用方法(六)
java中的return this什么时候用
11.@SuppressWarnings注解
java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一。可以标注在类、字段、方法、参数、构造方法,以及局部变量上。
作用:告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
@SuppressWarnings("unchecked")
告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
参考:http://blog.sina.com.cn/s/blog_ad8b5870010166vt.html
Java魔法堂:注解用法详解——@SuppressWarnings
例如:
12.属性解析
13.抽象方法
1 用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。例如 :
abstract class Animal { //用abstract来定义一个Animal为抽象类
}
public abstract void enjoy(); //用abstract来定义一个抽象方法"enjoy"
2 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
3 抽象类不能被实例化。
4 抽象方法只需声明,而不需实现某些功能。
14.获取包名路径下的 class 文件或目录
15.内部类
参考:主题:【解惑】领略内部类的“内部”
内部类有两种情况:
(1) 在类中定义一个类(私有内部类,静态内部类)
(2) 在方法中定义一个类(局部内部类,匿名内部类)
对内部类进行编译后发现有两个class文件:Outer.class 和Outer$Inner.class 。
这说明内部类Inner仍然被编译成一个独立的类(Outer$Inner.class),而不是Outer类的某一个域。 虚拟机运行的时候,也是把Inner作为一种常规类来处理的。
编译器对类中内部类做的手脚吧:
(1) 在内部类中偷偷摸摸的创建了包可见构造器,从而使外部类获得了创建权限。
(2) 在外部类中偷偷摸摸的创建了访问私有变量的静态方法,从而 使 内部类获得了访问权限。
这样,类中定义的内部类无论私有,公有,静态都可以被包围它的外部类所访问。
方法内部类也有两个特点
(1) 方法中的内部类没有访问修饰符, 即方法内部类对包围它的方法之外的任何东西都不可见。
(2) 方法内部类只能够访问该方法中的局部变量,所以也叫局部内部类。而且这些局部变量一定要是final修饰的常量。
内部类的特点总结
(1) 在方法间定义的非静态内部类:
● 外围类和内部类可互相访问自己的私有成员。
● 内部类中不能定义静态成员变量。
(2) 在方法间定义的静态内部类:
● 只能访问外部类的静态成员。
(3) 在方法中定义的局部内部类:
● 该内部类没有任何的访问控制权限
● 外围类看不见方法中的局部内部类的,但是局部内部类可以访问外围类的任何成员。
● 方法体中可以访问局部内部类,但是访问语句必须在定义局部内部类之后。
● 局部内部类只能访问方法体中的常量,即用final修饰的成员。
(4) 在方法中定义的匿名内部类:
● 没有构造器,取而代之的是将构造器参数传递给超类构造器。
16.匿名内部类
抽象类
调用比较
输出都是一样的
参考:java中的匿名内部类总结
java中匿名内部类的两种实现方式
匿名内部类的两种实现方式:
第一种,继承一个类,重写其方法;第二种,实现一个接口(可以是多个),实现其方法。
匿名内部类有了自己的实现。
使用匿名内部类是因为我这地方需要有点什么特殊的实现,所以我就在这地方把具体实现也给了出来了,然后我就在这地方获取它的实例,调用它的方法。
匿名内部类就是重写父类或接口的方法。
匿名内部类是没有名字的,所以我们没办法获得其类型,而只能把它当作超类或接口类型来使用。
17.final关键字
final这个关键字的含义是“这是无法改变的”或者“终态的”;
那么为什么要阻止改变呢?
java语言的发明者可能由于两个目的而阻止改变:
1).效率问题:
jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法,
用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的系能;
2). 设计所需:
众所周知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递;
【final关键字的使用方法】:
【修饰变量】:
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
【修饰方法】:
final方法不能被子类方法覆盖,但可以被继承。
【修饰类】:
final类不能被继承,没有子类,final类中所有方法都是final的。
比如util类
Servlet3.0提供@WebListener注解将一个实现了特定监听器接口的类定义为监听器,这样我们在web应用中使用监听器时,也不再需要在web.xml文件中配置监听器的相关描述信息了。
Web应用启动时就会初始化这个监听器
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContex销毁");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContex初始化");
System.out.println(sce.getServletContext().getServerInfo());
}
}
参考:Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
2.ServletRegistration
只能在webapp启动在初始化时进行完成注册,可能是为了安全考虑吧.
在Servlet3.0中可以动态注册Servlet,Filter,Listener
servlet 3.0笔记之servlet的动态注册
第十六章_动态注册和Servlet容器初始化
3.setAccessible(true)
Method actionMethod
actionMethod.setAccessible(true); // 取消类型安全检测(可提高反射性能)
4.instanceof
instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
java中instanceof用法
下面是调用Spring的函数
public class LogBeforeAdvice implements MethodBeforeAdvice { private Logger logger=Logger.getLogger(this.getClass().getName()); public void before(Method method,Object[] args,Object target) throws Throwable{
注意:getClass返回的是Class类型
这里也可以用if(args[0].getClass().getName().contains("com.xxx"))来判断是否指定类,但是没用instanceof直观
5.判断Map是否为空
public static boolean isEmpty(Map map) { return (map == null || map.isEmpty()); }
6.Map.Entry
// 初始化请求属性 Map<String, Object> data = view.getData(); if (MapUtil.isNotEmpty(data)) { for (Map.Entry<String, Object> entry : data.entrySet()) { request.setAttribute(entry.getKey(), entry.getValue()); } }
视图操作 :处理映像中键/值对组
Set keySet(): 返回映像中所有关键字的视图集
“因为映射中键的集合必须是唯一的,您用Set支持。你还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是你不能添加任何元素。”
Collection values():返回映像中所有值的视图集
“因为映射中值的集合不是唯一的,您用Collection支持。你还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是你不能添加任何元素。”
Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对
“因为映射是唯一的,您用Set支持。你还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是你不能添加任何元素。”
Map.Entry接口
Map的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。
通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。当条目通过迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。
(1) Object getKey(): 返回条目的关键字
(2) Object getValue(): 返回条目的值
(3) Object setValue(Object value): 将相关映像中的值改为value,并且返回旧值
7.getRequestDispatcher()与sendRedirect()的区别
1.request.getRequestDispatcher()是请求转发,前后页面共享一个request ;
response.sendRedirect()是重新定向,前后页面不是一个request。
request.getRequestDispather();返回的是一个RequestDispatcher对象。
2.RequestDispatcher.forward()是在服务器端运行;
/** * 转发请求 */ public static void forwardRequest(String path, HttpServletRequest request, HttpServletResponse response) { try { request.getRequestDispatcher(path).forward(request, response); } catch (Exception e) { logger.error("转发请求出错!", e); throw new RuntimeException(e); } }
8.引用JSTL
The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
http://blog.csdn.net/lzz313/article/details/7554736 http://blog.sina.com.cn/s/blog_7ffb8dd501013fvl.html
<!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency>
9.ThreadLocal
每个线程相互独立了,同样是 static 变量,对于不同的线程而言,它没有被共享,而是每个线程各一份,这样也就保证了线程安全。 也就是说,TheadLocal 为每一个线程提供了一个独立的副本!
public class SequenceB implements Sequence { private static ThreadLocal<Integer> numberContainer = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; } }; public int getNumber() { numberContainer.set(numberContainer.get() + 1); return numberContainer.get(); } public static void main(String[] args) { Sequence sequence = new SequenceB(); ClientThread thread1 = new ClientThread(sequence); ClientThread thread2 = new ClientThread(sequence); ClientThread thread3 = new ClientThread(sequence); thread1.start(); thread2.start(); thread3.start(); } }
ThreadLocal 的 API,其实很简单
public void set(T value):将值放入线程局部变量中
public T get():从线程局部变量中获取值
public void remove():从线程局部变量中移除值(有助于 JVM 垃圾回收)
protected T initialValue():返回线程局部变量中的初始值(默认为 null)
为什么 initialValue() 方法是 protected 的呢?就是为了提醒程序员们,这个方法是要你们来实现的,请给这个线程局部变量一个初始值吧。
ThreadLocal 具体有哪些使用案例呢:通过 ThreadLocal 存放 JDBC Connection,以达到事务控制的能力。
当您在一个类中使用了 static 成员变量的时候,一定要多问问自己,这个 static 成员变量需要考虑“线程安全”吗?
也就是说,多个线程需要独享自己的 static 成员变量吗?如果需要考虑,那就请用 ThreadLocal 吧!
参考: ThreadLocal 那点事儿
10.return this
return this 返回的是当前方法所在的类的实例,例如 StringBuilder 中的 append,这样做的好处就是可以 append("XXX").append("XXX").append("XXX")....
public class ReturnThis { public int age; public ReturnThis grow() { age++; //return this,返回调用该方法的对象 return this; } public static void main(String[] args) { ReturnThis rt = new ReturnThis(); //可以连续调用同一个方法 rt.grow() .grow() .grow(); System.out.println("rt的age属性值是:" + rt.age); } }
这样连续调用同一个方法。
参考:初学Java,方法中返回this,连续调用方法(六)
java中的return this什么时候用
11.@SuppressWarnings注解
java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一。可以标注在类、字段、方法、参数、构造方法,以及局部变量上。
作用:告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
@SuppressWarnings("unchecked")
告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
参考:http://blog.sina.com.cn/s/blog_ad8b5870010166vt.html
Java魔法堂:注解用法详解——@SuppressWarnings
例如:
@SuppressWarnings("unchecked") public static <T> T getInstance(String cacheKey, Class<T> defaultImplClass) {
12.属性解析
/** * 获取字符型属性 */ public static String getString(Properties props, String key) { String value = ""; if (props.containsKey(key)) { value = props.getProperty(key); } return value; }
13.抽象方法
1 用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。例如 :
abstract class Animal { //用abstract来定义一个Animal为抽象类
}
public abstract void enjoy(); //用abstract来定义一个抽象方法"enjoy"
2 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
3 抽象类不能被实例化。
4 抽象方法只需声明,而不需实现某些功能。
public abstract class ClassTemplate { ... private void doAddClass(List<Class<?>> classList, String className) { // 加载类 Class<?> cls = ClassUtil.loadClass(className, false); // 判断是否可以添加类 if (checkAddClass(cls)) { // 添加类 classList.add(cls); } } /** * 验证是否允许添加类 */ public abstract boolean checkAddClass(Class<?> cls); }
14.获取包名路径下的 class 文件或目录
// 获取包名路径下的 class 文件或目录 File[] files = new File(packagePath).listFiles(new FileFilter() { @Override public boolean accept(File file) { return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory(); } });
15.内部类
参考:主题:【解惑】领略内部类的“内部”
内部类有两种情况:
(1) 在类中定义一个类(私有内部类,静态内部类)
(2) 在方法中定义一个类(局部内部类,匿名内部类)
对内部类进行编译后发现有两个class文件:Outer.class 和Outer$Inner.class 。
这说明内部类Inner仍然被编译成一个独立的类(Outer$Inner.class),而不是Outer类的某一个域。 虚拟机运行的时候,也是把Inner作为一种常规类来处理的。
编译器对类中内部类做的手脚吧:
(1) 在内部类中偷偷摸摸的创建了包可见构造器,从而使外部类获得了创建权限。
(2) 在外部类中偷偷摸摸的创建了访问私有变量的静态方法,从而 使 内部类获得了访问权限。
这样,类中定义的内部类无论私有,公有,静态都可以被包围它的外部类所访问。
方法内部类也有两个特点
(1) 方法中的内部类没有访问修饰符, 即方法内部类对包围它的方法之外的任何东西都不可见。
(2) 方法内部类只能够访问该方法中的局部变量,所以也叫局部内部类。而且这些局部变量一定要是final修饰的常量。
内部类的特点总结
(1) 在方法间定义的非静态内部类:
● 外围类和内部类可互相访问自己的私有成员。
● 内部类中不能定义静态成员变量。
(2) 在方法间定义的静态内部类:
● 只能访问外部类的静态成员。
(3) 在方法中定义的局部内部类:
● 该内部类没有任何的访问控制权限
● 外围类看不见方法中的局部内部类的,但是局部内部类可以访问外围类的任何成员。
● 方法体中可以访问局部内部类,但是访问语句必须在定义局部内部类之后。
● 局部内部类只能访问方法体中的常量,即用final修饰的成员。
(4) 在方法中定义的匿名内部类:
● 没有构造器,取而代之的是将构造器参数传递给超类构造器。
private void addClass(List<Class<?>> classList, String packagePath, String packageName) {
try {
// 获取包名路径下的 class 文件或目录 File[] files = new File(packagePath).listFiles(new FileFilter() { @Override public boolean accept(File file) { return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory(); } });
16.匿名内部类
抽象类
abstract class Person { public abstract void eat(); }实现类
public class Child extends Person{ public void eat() { System.out.println("eat something"); } }
调用比较
//正常调用 Person p = new Child(); p.eat(); //匿名内部类 Person p2 = new Person(){ public void eat() { System.out.println("eat something"); } };
输出都是一样的
参考:java中的匿名内部类总结
java中匿名内部类的两种实现方式
匿名内部类的两种实现方式:
第一种,继承一个类,重写其方法;第二种,实现一个接口(可以是多个),实现其方法。
匿名内部类有了自己的实现。
使用匿名内部类是因为我这地方需要有点什么特殊的实现,所以我就在这地方把具体实现也给了出来了,然后我就在这地方获取它的实例,调用它的方法。
匿名内部类就是重写父类或接口的方法。
匿名内部类是没有名字的,所以我们没办法获得其类型,而只能把它当作超类或接口类型来使用。
17.final关键字
final这个关键字的含义是“这是无法改变的”或者“终态的”;
那么为什么要阻止改变呢?
java语言的发明者可能由于两个目的而阻止改变:
1).效率问题:
jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法,
用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的系能;
2). 设计所需:
众所周知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递;
【final关键字的使用方法】:
【修饰变量】:
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
【修饰方法】:
final方法不能被子类方法覆盖,但可以被继承。
【修饰类】:
final类不能被继承,没有子类,final类中所有方法都是final的。
比如util类
public final class FileUtil { private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class); /** * 获取真实文件名(自动去掉文件路径) */ public static String getRealFileName(String fileName) { return FilenameUtils.getName(fileName); }
相关文章推荐
- SPI与IIC
- 《机电传动控制》第三周仿真作业
- 利用sklearn计算文本相似性
- 算法学习
- convex hull trick CF344.E
- 服务器端开发技术
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- 栈与队列的真相(概述)
- CodeForces - 630B Moore's Law (快速幂)
- Codeforces 651C - Watchmen
- 软考中高项学员:2016年3月7日作业
- 2016.3.7
- c语言之指针调用注意
- Codeforces 651C - Watchmen
- 第3章 jQuery之选择器
- 服务器端开发总结
- c++单链表【构造函数、运算符重载、析构函数、增删查改等】
- 明天去借书
- Android中ArrayAdapt&SimpleAdapt的使用
- HDFS的API操作