前几天在看一个设计模式的时候,看到了一个新的获得对象的方式。感觉蛮有趣的,然后去网上搜了搜果然有所收获。于是动手写了写代码,稍微了解了一下:
1.最传统的方式: 申明一个引用 直接指向 Object o = new Object(); 这种方法最常见了 暂时也没想出有啥特殊之处 等以后想起啥来再来补充吧。
2.第二种方式 : 反射 调用java.lang.reflect.Constructor类的newInstance()方法。这个方法是我在练习工厂模式的时候发现的代码不多,贴出来讲吧。
public class PrivateClass
{
private PrivateClass(){}
public void say()
{
System.out.println("我的构造器是私有的");
}
}
随便建一个类,重点是是把构造器设为private的。这样的话外部的其他类就不能通过new 的方法创建此类的对象了,
而且他本身没有像单例模式那样提供提供对象引用的接口,这样的话这个类的对象似乎是没办法创建和获得的。
反射在这时候就用上了:
public class TestReflect
{
public static void main(String[] args)
{
try {
PrivateClass myclass = (PrivateClass)Class.forName(PrivateClass.class.getName()).newInstance();
myclass.say();
} catch (Exception e) {
e.printStackTrace();
}
}
}
上述代码中最长的部分就是通过反射方法获得PrivateClass对象的。class.forName() 里的参数是需要获得的对象的类的名字,这里直接用字符串"PrivateClass"也可以。 class.forName() 获得的对象是Object类型的 所以这里需要强制类型转换一下
3.第三种方式就是所谓的单例模式,其实呢 单例模式内部也是用new的方法创建对象并获得引用的,只是其内部有一方法可以把这个对象的引用传到所有需要的地方。
public class Singleton
{
static Singleton sg = new Singleton();
private Singleton(){}
public Singleton getInstance()
{
return sg;
}
}
它的构造器同样是私有的,所以外部不能创建其对象(当然,除了刚刚讲过的方式)。但他在内部创建一个对象,并用一个sg引用指向他,然后通过getInstance()方法获得这个引用。这样虽然引用可能会被不同的类所调用,但对象只有这一个。
4. 第四中方法 clone(克隆)
一个对象想要能够呗克隆,那他的类必须实现Cloneable接口而且JDK中Object# clone()方法的原型是:
protected native Object clone() throws CloneNotSupportedException;
方法修饰符是protected,而不是public。这种访问的不可见性使得我们对Object#clone()方法不可见。
所以,必需重写Object的clone方法后才能使用。
public class MyClone implements Cloneable
{
public MyClone(){}
@Override
protected Object clone() throws CloneNotSupportedException {
MyClone mc = (MyClone)super.clone();
return mc;
}
public void say()
{
System.out.println("hello clone");
}
}
既然叫克隆,那必然有原型才能克隆,他的构造器设为public ,外部可以new它的对象。
MyClone mc = new MyClone();//这为原型
try{
MyClone mc1 = (MyClone) mc.clone();//克隆获得对象
mc1.say();
}catch(Exception e)
{
e.printStackTrace();
}
5.序列化Serializable 或 Externalizable
Serializable 或 Externalizable 是Java的两个接口,位于java.io包里面。如果一个对象想要能被序列化的话,就得实现以上两个接口中的一个。其实Externalizable接口是继承自Serializable接口的,如果实现Serializable的话,不用实现任何方法(就像给那个类贴个“允许”序列化的标签一样),而如果实现Externalizable接口的话,需要实现writeExternal(ObjectOutput out) 和 readExternal(ObjectInput in)两个方法来进行对象的读写。
保存对象的时候可以用如下写法
FileOutputStream fout=new FileOutputStream("***"); 存储到文件***中
ObjectOutputStream oout=new ObjectOutputStream(fout);
oout.writeObject(****);****代表要存储的对象
提取对象的时候进行相反的操作即可
ileInputStream fin=new FileInputStream("****"); //指出对象存储的文件***
ObjectInputStream oin=new ObjectInputStream(fin);
Student stu1=(Student)oin.readObject(); //读出来的对象是Object类型的 所以需要强制类型转换一下
对象的序列化实现了对对象的直接读写,特别明显的应用是在游戏中的“存档”功能。
6.使用Spring的DI
在下才疏学浅,最后一种方式没有接触过,等以后熟悉点了再来补冲