java 有2种新建对象的方法
1, ClassName objectName = new ClassName();
2, Class cls = Class.forName("ClassName");
ClassName objectName = (ClassName)cls.newInstance();
普遍肯定都是第一种用得多吧,那么第二种又有什么用呢。
Monday最近在做服务器的时候遇到这种问题。
客户端向服务器发送消息,通常都带有一定协议,具体是要按照项目本身而定。
例如
消息体的头4个byte(一个int) 表示这个消息体的总大小
第5个byte 存放消息的类型
从第6个byte开始,存储消息的实体
直接从将原始接收到的消息用于业务逻辑是不太可行的,可以通过一定的解码转换成对象,之后可以更好的操作业务。
根据第5个byte的值,将第6个byte之后的转换成对象。
所以这么粗略一想,代码应该会有下面2种情况
Message msg = null;
switch(receive[5])
case 0:
msg = new Message01();
//do something
case 1:
msg = new Message02();
//do something
...
或者
Class messageName = getMessaeType(msg[])
Message msg = (Message)messageName.newInstance();
Monday是个比较抠细节的人,究竟哪种比较快呢。
写了个简单的测试代码(其实就是循环个N遍,看谁的快。)
static class NewThread extends Thread{
@Override
public void run() {
super.run();
long star = System.currentTimeMillis();
for(int i = 0; i < COUNT; i++){
NewInstanceTest a = new NewInstanceTest();
}
System.out.println("NewThread : " + (System.currentTimeMillis() - star));
}
}
static class InstanceThread extends Thread{
@Override
public void run() {
super.run();
Class cls = null;
long star = System.currentTimeMillis();
try {
cls = Class.forName("com.monday.switchandfunctiontest.NewInstanceTest");
for(int i = 0; i < COUNT; i ++){
NewInstanceTest test = (NewInstanceTest) cls.newInstance();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("InstanceThread : " + (System.currentTimeMillis() - star));
}
}
最后输出
NewThread : 15813 《== 这个是用new的方法
InstanceThread : 314860 《== 这个是用newInstance的方法
相差了近20倍的效率。