1、Integer 相等比较
public static void main(String[] args) {
Integer d =127;
Integer f = 127;
Integer e = 130;
Integer g = 130;
System.out.println(d==f);//true
System.out.println(e==g);// false
}
上述:总所周知,对象用==比较的话,是比较其地址,那么上述为何会出现2个结果呢?看源码,发现当Integer的值不在-128~127之间的话,那么就会重新new一个对象。故导致看到的结果。
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
2、继承
public class A {
public void show(A obj){
System.out.println("A and A");
}
public void show(B obj){
System.out.println("A and B");
}
}
public class B extends A{
public void show(A obj){
System.out.println("B and A");
}
public void show(C obj){
System.out.println("B and C");
}
}
public class C extends B {
}
public class D extends B {
}
public static void main(String[] args) {
A a = new A();
A a1 = new B();
B b = new B();
C c = new C();
D d = new D();
a.show(c); // A and B 先去A类中查找发现没有该方法,但是C extends B 故结果A and B
a.show(d);// A and B 同理上面
a.show(b);// A and B
/**
* 这里虽然a1的类型是A 但是 实际引用的是B类 new B()会在堆区分配内存空间
*当a1.show(c)方法时,jvm会根据a1持有的引用定位到堆区的B实例
* 再根据B持有的引用 定位到方法区B类的类型(这时候是A)信息 获得show的字节,
* 如果有重写show方法的话,那么就是调用B类中的show
*/
a1.show(c);// A and B
a1.show(d);// A and B
a1.show(a);// B and A 将优先和B类本身包含的实例方法动态绑定,如果没有这个实例方法,才会从父类A中继承来的
}
3、单例
关于spring创建实例默认是单例模式,如想要配置成多例该怎么办呢?
其实很简单 在spring的配置文件中具体的bean配置scope=“prototype”这样就是多例了。
<bean id="loginAction" class="com.business.common.action.LoginAction" scope="prototype"/>
关于单例的写法有如下几种实现方式
/**
*懒汉式 线程不安全
*/
public class TestSingleton {
private static TestSingleton testSingleton = null;
private TestSingleton(){}; // 防止构建该实例
public static TestSingleton getSingleton(){
if(testSingleton == null){
testSingleton = new TestSingleton();
}
return testSingleton;
}
}
/**
* 饿汉式 天生就线程安全,类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了
*/
public class TestSingleton {
private static TestSingleton singleton = new TestSingleton();
private TestSingleton(){};
public static TestSingleton getIntance(){
return singleton;
}
}
public class TestSingleton {
private static volatile TestSingleton singleton;
private TestSingleton(){};
/**
* 双重校验 线程安全
* @return
*/
public static TestSingleton getInstance(){
// 先判断singleton该实例是否存在,若存在则直接返回,不存在的话创建。
if(null ==singleton){
// 若不写上面的if判断的话,那么每次线程进来都需要发生锁等待,避免了每次都同步的性能损耗
synchronized (TestSingleton.class){
if(null ==singleton){
singleton = new TestSingleton();
}
}
}
return singleton;
}
}
那么Spring对单例的底层实现,到底是饿汉式单例还是懒汉式单例呢?呵呵,都不是。Spring框架对单例的支持是采用单例注册表的方式进行实现的,源码如下:
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory{
/**
* 充当了Bean实例的缓存,实现方式和单例注册表相同
*/
private final Map singletonCache=new HashMap();
public Object getBean(String name)throws BeansException{
return getBean(name,null,null);
}
...
public Object getBean(String name,Class requiredType,Object[] args)throws BeansException{
//对传入的Bean name稍做处理,防止传入的Bean name名有非法字符(或则做转码)
String beanName=transformedBeanName(name);
Object bean=null;
//手工检测单例注册表
Object sharedInstance=null;
//使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高
synchronized(this.singletonCache){
sharedInstance=this.singletonCache.get(beanName);
}
if(sharedInstance!=null){
...
//返回合适的缓存Bean实例
bean=getObjectForSharedInstance(name,sharedInstance);
}else{
...
//取得Bean的定义
RootBeanDefinition mergedBeanDefinition=getMergedBeanDefinition(beanName,false);
...
//根据Bean定义判断,此判断依据通常来自于组件配置文件的单例属性开关
//<bean id="date" class="java.util.Date" scope="singleton"/>
//如果是单例,做如下处理
if(mergedBeanDefinition.isSingleton()){
synchronized(this.singletonCache){
//再次检测单例注册表
sharedInstance=this.singletonCache.get(beanName);
if(sharedInstance==null){
...
try {
//真正创建Bean实例
sharedInstance=createBean(beanName,mergedBeanDefinition,args);
//向单例注册表注册Bean实例
addSingleton(beanName,sharedInstance);
}catch (Exception ex) {
...
}finally{
...
}
}
}
bean=getObjectForSharedInstance(name,sharedInstance);
}
//如果是非单例,即prototpye,每次都要新创建一个Bean实例
//<bean id="date" class="java.util.Date" scope="prototype"/>
else{
bean=createBean(beanName,mergedBeanDefinition,args);
}
}
...
return bean;
}
}
那么spring在bean实例时是线程安全。
一种特殊化的单例模式,它被称为单例注册表:
Import java.util.HashMap;
Public class RegSingleton{
Static private HashMap registry=new HashMap();
//静态块,在类被加载时自动执行
Static{
RegSingleton rs=new RegSingleton();
Registry.put(rs.getClass().getName(),rs);
}
//受保护的默认构造函数,如果为继承关系,则可以调用,克服了单例类不能为继承的缺点
Protected RegSingleton(){}
//静态工厂方法,返回此类的唯一实例
public static RegSingleton getInstance(String name){
if(name==null){
name=” RegSingleton”;
}if(registry.get(name)==null){
try{
registry.put(name,Class.forName(name).newInstance());
}Catch(Exception ex){ex.printStackTrace();}
}
Return (RegSingleton)registry.get(name);
}
}
4、JAXB bean to xml
需要生成如下对应的xml格式:
<T_TASK_APPROVE>
<HEAD>
<MSGCODE>T_TASK_APPROVE_</MSGCODE>
<MSGID>T_TASK_APPROVE</MSGID>
<MSGNAME>统一审批中心接收审批服务</MSGNAME>
<SOURCESYS>hr</SOURCESYS>
<TARGETSYS>HBTYSP</TARGETSYS>
</HEAD>
<DATA>
<ROW>
<PROPERTIES code="APP_ID">qq</PROPERTIES>
<PROPERTIES code="service_ID">12345</PROPERTIES>
</ROW>
</DATA>
</T_TASK_APPROVE>
1、首先创建最外层的结构
@XmlRootElement(name="T_TASK_APPROVE")
public class BackLogData {
private BackLogHeadData head;
private BackLogPropertie data;
@XmlElement(name="HEAD",nillable = true)
public BackLogHeadData getHead() {
return head;
}
public void setHead(BackLogHeadData head) {
this.head = head;
}
@XmlElement(name="DATA")
public BackLogPropertie getData() {
return data;
}
public void setData(BackLogPropertie data) {
this.data = data;
}
}
2、构建head中的数据
@XmlRootElement
public class BackLogHeadData {
private String msgcode;
private String msgid;
private String msgname;
private String sourcesys;
private String targetsys;
private String createtime;
@XmlElement(name="MSGCODE",nillable = true)
public String getMsgcode() {
return this.msgcode;
}
public void setMsgcode(String msgcode) {
this.msgcode = msgcode;
}
@XmlElement(name="MSGID",nillable = true)
public String getMsgid() {
return this.msgid;
}
public void setMsgid(String msgid) {
this.msgid = msgid;
}
@XmlElement(name="MSGNAME",nillable = true)
public String getMsgname() {
return this.msgname;
}
public void setMsgname(String msgname) {
this.msgname = msgname;
}
@XmlElement(name="SOURCESYS",nillable = true)
public String getSourcesys() {
return this.sourcesys;
}
public void setSourcesys(String sourcesys) {
this.sourcesys = sourcesys;
}
@XmlElement(name="TARGETSYS",nillable = true)
public String getTargetsys() {
return this.targetsys;
}
public void setTargetsys(String targetsys) {
this.targetsys = targetsys;
}
@XmlElement(name="CREATETIME",nillable = true)
public String getCreatetime() {
return this.createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
}
3、构造DATA节点中的数据
@XmlRootElement
public class BackLogPropertie {
private List<Propertie> properties;
@XmlElementWrapper(name="ROW")
@XmlElement(name="PROPERTIES")
public List<Propertie> getProperties() {
return properties;
}
public void setProperties(List<Propertie> properties) {
this.properties = properties;
}
}
生成xml代码
public static void main(String args[]) {
BackLogData backLogData = new BackLogData();
BackLogHeadData head = new BackLogHeadData();
head.setMsgcode("T_TASK_APPROVE_");
head.setMsgid("T_TASK_APPROVE");
head.setMsgname("统一审批中心接收审批服务");
head.setSourcesys("hr");
head.setTargetsys("HBTYSP");
BackLogPropertie backLogPropertie = new BackLogPropertie();
List<Propertie> properties = new ArrayList<>();
Propertie appId = new Propertie();
appId.setCode("APP_ID");
appId.setValue("qq");
properties.add(appId);
Propertie serviceId = new Propertie();
serviceId.setCode("service_ID");
serviceId.setValue("12345");
properties.add(serviceId);
backLogPropertie.setProperties(properties);
backLogData.setHead(head);
backLogData.setData(backLogPropertie);
String xmlData = XmlBuilder.convertToXml(backLogData);
System.out.println(xmlData);
}