1.静态代码块和非静态代码块以及构造函数
public class Parent { static String name = "hello"; //非静态代码块 { System.out.println("1"); } //静态代码块 static { System.out.println("2"); } public Parent() { System.out.println("3"); } }
public class Child extends Parent { static String childName = "hello"; { System.out.println("4"); } static { System.out.println("5"); } public Child() { System.out.println("6"); } }调用测试
public class StaticCodeBlockOrderTest { public static void main(String[] args) { new Child(); } }
对象的初始化顺序:
首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,
如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。
子类的非静态代码块执行完毕再去执行子类的构造方法。
参考:java中静态代码块的用法 static用法详解
静态代码块的应用
需要一个Util类,需要系统初始化的时候就初始化一个hashMap,部分代码省略以...代替
private static Map<String, List<String>> smap = new HashMap<String, List<String>>(); static { for (int i = 0; i < k; i++) { List<String> ls = new ArrayList<String>(); ls.add(...); ls.add(...); smap.put(..., ls); } }
这个一样的用法:Map的静态赋值
2.泛型 Class<T>和Class<?>的差异
public class Box<T> { private T t; public Box(){ } public Box(T data){ this.t=data; } public T getT() { return t; } public void setT(T t) { this.t = t; } }调用
public static void main(String[] args) { Box<String> s=new Box<String>("abc"); Box<Integer> i=new Box<Integer>(123); System.out.println("s class:" + s.getClass()); System.out.println("i class:" + i.getClass()); System.out.println(s.getClass() == i.getClass()); }输出
为什么有Class<T>还需要Class<?>呢?
其实看这个就明白了
在其他类中例如这个Test里,你可以定义
public static void getData(Box<String> data){ System.out.println("data :" + data.getT()); }
public static void getData(Box<Integer> data){ System.out.println("data :" + data.getT()); }
但是你要是同时定义这2个就会报错
名称冲突: getData(Box<Integer>)和getData(Box<String>)具有相同疑符
使用通配符?就可以解决这个问题
public class TestMain { public static void main(String[] args) { Box<String> s=new Box<String>("abc"); Box<Integer> i=new Box<Integer>(123); System.out.println("s class:" + s.getClass()); System.out.println("i class:" + i.getClass()); System.out.println(s.getClass() == i.getClass()); getData(s); getData(i); } public static void getData(Box<?> data){ System.out.println("data :" + data.getT()); } }
参考:
Java总结篇系列:Java泛型
java中的泛型总结
再来看看Class<?>的用处
public class TestMain { public static void main(String[] args) { Box<String> s=new Box<String>("http://blog.csdn.net/unix21"); Box<Integer> i=new Box<Integer>(123); System.out.println("s class:" + s.getClass()); System.out.println("i class:" + i.getClass()); System.out.println(s.getClass() == i.getClass()); getData(Box.class); } public static void getData(Class<?> clz){ try { System.out.println(clz); System.out.println("clz.hashCode():" + clz.hashCode()); Object o=clz.newInstance(); o.hashCode(); System.out.println("o.hashCode():" + o.hashCode()); } catch (Exception e) { System.out.println(e); } } }
不能将 "class java.lang.Class (no class loader)" 的实例强制转换为 "class test.Box (loaded by instance of sun.misc.Launcher$AppClassLoader(id=144))" 的实例
说明还没有class loader
3.Object类型
定义的所有类默认都是子类,所有的类都是以标准类Object为基础,Object类型的变量可以存储指向任意类类型对象的索引。
当要为一个方法来处理未知类型的对象时,这很有用。
//存储的地方 HashMap<String , Object> map = new HashMap<String , Object>(); User u1=new User(); u1.setId(1); u1.setName("ww1"); //Object可以塞任意类型 map.put("user",u1); User u=(User)map.get("user"); response.getWriter().println("Hello Servlet >>>"+u.getName()); String clazz ="com.w1.User"; //bean.getAttributeValue("class"); try { //反射 Object o = Class.forName(clazz).newInstance(); map.put("user2",o); User u2=(User)map.get("user2"); u2.setName("ww223"); response.getWriter().println("Hello Servlet >>>"+u2.getName()); } catch (Exception e) { e.printStackTrace(); }
4.类名.class, class.forName(), getClass()区别
1:Class cl=A.class;
JVM将使用类A的类装载器, 将类A装入内存(前提是:类A还没有装入内存),不对类A做类的初始化工作.返回类A的Class的对象。
2:Class cl=对象引用o.getClass();
返回引用o运行时真正所指的对象(因为:子对象的引用可能会赋给父对象的引用变量中)所属的类的Class的对象 。
3:Class.forName("类名");
.装入类A,并做类的初始化
.getClass()是动态的,其余是静态的。
.class和class.forName()只能返回类内field的默认值,getClass可以返回当前对象中field的最新值
Class.forName() 返回的是一个类,.newInstance() 后才创建一个对象,Class.forName()的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的。
public class Person { private String name = "Alfira"; public void getName() { System.out.println(name); } public void setName(String name, int a) { this.name = name + a; } }
private static void show(String name) { try { // JVM将使用类A的类装载器,将类A装入内存(前提是:类A还没有装入内存),不对类A做类的初始化工作 Class classtype3 = Person.class; // 获得classtype中的方法 Method getMethod3 = classtype3.getMethod("getName", new Class[] {}); Class[] parameterTypes3 = { String.class, int.class }; Method setMethod3 = classtype3.getMethod("setName", parameterTypes3); // 实例化对象,因为这一句才会输出“静态初始化”以及“初始化” Object obj3 = classtype3.newInstance(); // 通过实例化后的对象调用方法 getMethod3.invoke(obj3); // 获取默认值 setMethod3.invoke(obj3, "Setting new ", 3); // 设置 getMethod3.invoke(obj3); // 获取最新 System.out.println("----------------"); // 返回运行时真正所指的对象 Person p = new Person(); Class classtype = p.getClass();// Class.forName(name); // 获得classtype中的方法 Method getMethod = classtype.getMethod("getName", new Class[] {}); Class[] parameterTypes = { String.class, int.class }; Method setMethod = classtype.getMethod("setName", parameterTypes); getMethod.invoke(p);// 获取默认值 setMethod.invoke(p, "Setting new ", 1); // 设置 getMethod.invoke(p);// 获取最新 System.out.println("----------------"); // 装入类,并做类的初始化 Class classtype2 = Class.forName(name); // 获得classtype中的方法 Method getMethod2 = classtype2.getMethod("getName", new Class[] {}); Class[] parameterTypes2 = { String.class, int.class }; Method setMethod2 = classtype2.getMethod("setName", parameterTypes2); // 实例化对象 Object obj2 = classtype2.newInstance(); // 通过实例化后的对象调用方法 getMethod2.invoke(obj2); // 获取默认值 setMethod2.invoke(obj2, "Setting new ", 2); // 设置 getMethod2.invoke(obj2); // 获取最新 System.out.println("----------------"); } catch (Exception e) { System.out.println(e); } }
show("com.Person");
http://blog.163.com/granite8@126/blog/static/853746082008610102657141/
5.动态代理和cglib
public class SayHello { public void say(){ System.out.println("hello everyone"); } }
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz) { //设置需要创建子类的类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //通过字节码技术动态创建子类实例 return enhancer.create(); } //实现MethodInterceptor接口方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("前置代理"); //通过代理类调用父类中的方法 Object result = proxy.invokeSuper(obj, args); System.out.println("后置代理"); return result; } }
CglibProxy proxy = new CglibProxy(); //通过生成子类的方式创建代理类 SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class); proxyImp.say();
CGLib动态代理原理及实现
Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)[转]
cglib动态代理介绍(一)
6.模仿Spring实现
需要说这个作者写到这一系列文章非常好【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
代码:http://download.csdn.net/detail/jiuqiyuliang/8483981
这篇博文的目标是不仅形似Spring的IoC,而且要神似Spring的IoC,将对象的依赖关系进一步封装。
完整的项目结构
Dao接口和实现
public interface Dao { public void daoMethod(); }
public class Dao4MySqlImpl implements Dao { public void daoMethod(){ System.out.println("Dao4MySqlImpl.daoMethod()"); } }
public class Dao4OracleImpl implements Dao { public void daoMethod(){ System.out.println("Dao4OracleImpl.daoMethod()"); } }
public interface Service { public void serviceMethod(); }
public class ServiceImpl implements Service { private Dao dao; //依赖注入 public void setDao(Dao dao) { this.dao= dao; } @Override public void serviceMethod() { dao.daoMethod(); } }
public interface BeanFactory { Object getBean(String beanName); }
import java.util.ArrayList; import java.util.List; public class BeanDefinition { private String id; private String className; private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>(); public BeanDefinition(String id, String className) { this.id = id; this.className = className; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public List<PropertyDefinition> getPropertys() { return propertys; } public void setPropertys(List<PropertyDefinition> propertys) { this.propertys = propertys; } }
import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.xpath.XPath; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 容器 * * @author liang * */ public class ClassPathXmlApplicationContext implements BeanFactory { // 用于存放Bean private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>(); // 用于存放Bean的实例 private Map<String, Object> sigletons =new HashMap<String, Object>(); public ClassPathXmlApplicationContext(String fileName) { this.readXML(fileName); this.instanceBeans(); this.injectObject(); } /** * 为bean对象的属性注入值 */ private void injectObject() { for (BeanDefinition beanDefinition :beanDefines) { Object bean = sigletons.get(beanDefinition.getId()); if(bean != null){ try { // 通过Introspector取得bean的定义信息,之后再取得属性的描述信息,返回一个数组 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition:beanDefinition.getPropertys()){ for(PropertyDescriptor properdesc: ps){ if(propertyDefinition.getName().equals(properdesc.getName())){ // 获取属性的setter方法,private Method setter = properdesc.getWriteMethod(); if(setter != null){ Object value = sigletons.get(propertyDefinition.getRef()); // 允许访问私有方法 setter.setAccessible(true); // 把引用对象注入到属性 setter.invoke(bean, value); } break; } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 完成bean的实例化 */ private void instanceBeans() { for(BeanDefinition beanDefinition : beanDefines){ try { if(beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())){ sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance() ); } } catch (Exception e) { e.printStackTrace(); } } } /** * 读取xml配置文件 */ private void readXML(String fileName) { // 创建SAXBuilder对象 SAXBuilder saxBuilder = new SAXBuilder(); try { // 读取资源,获得document对象 Document doc = saxBuilder.build(this.getClass().getClassLoader() .getResourceAsStream(fileName)); // 获取根元素 Element rootEle = doc.getRootElement(); // 从根元素获得所有的子元素,建立元素集合 List listBean = XPath.selectNodes(rootEle, "/beans/bean"); // 遍历根元素的子元素集合,扫描配置文件中的bean for (int i = 0; i < listBean.size(); i++) { // 将根元素beans下的bean子元素作为一个新的子根元素 Element elementBean = (Element) listBean.get(i); //获取id属性值 String id = elementBean.getAttributeValue("id"); //获取class属性值 String clazz = elementBean.getAttributeValue("class"); BeanDefinition beanDefine = new BeanDefinition(id,clazz); // 获取子根元素bean下的所有property子元素 List listProperty = elementBean.getChildren("property"); // 遍历子根元素的子元素集合(即遍历property元素) for (int j = 0; j < listProperty.size(); j++) { // 获取property元素 Element elmentProperty = (Element)listProperty.get(j); // 获取name属性值 String propertyName = elmentProperty.getAttributeValue("name"); // 获取ref属性值 String propertyref = elmentProperty.getAttributeValue("ref"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName,propertyref); beanDefine.getPropertys().add(propertyDefinition); } // 将javabean添加到集合中 beanDefines.add(beanDefine); } } catch (Exception e) { e.printStackTrace(); } } /** * 获取bean实例 */ @Override public Object getBean(String beanName) { return this.sigletons.get(beanName); } }
public class PropertyDefinition { private String name; private String ref; public PropertyDefinition(String name, String ref) { this.name = name; this.ref = ref; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } }
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="dao" class="com.tgb.container.dao.impl.Dao4MySqlImpl" /> <bean id="service" class="com.tgb.container.service.impl.ServiceImpl"> <property name="dao" ref="dao"></property> </bean> </beans>
Smart Framework:轻量级 Java Web 框架
Smart Framework是一个完整的类似Spring但是更轻量级的项目,学习框架的最佳材料之一。