共有5种方式:


1.new


2.反射newInstance


3.克隆clone


4.序列化Serializable


5.使用Spring的DI



1.new
通常都是使用java的关键字new来创建对象实例。

若有一个Something类,则可以通过下面的语句创建Something类的对象实例并指定到变量obj。

Java代码
Student stu=new Student();

2.反射 newInstance
利用java.lang.Class类的newInstance方法,则可根据Class对象的实例,建立该Class所表示的类的对象实例。

创建Something类的对象实例可以使用下面的语句(这样需要一个已经存在的对象实例)。

Java代码

Student stu= Student Class.forName("cn.test.Student").newInstance();
如果包下不存在相应.class文件,则会抛出ClassNotFoundException。

注意 :newInstance创建对象实例的时候会调用无参的构造函数,所以必需确保类中有无参数的构造函数,否则将会

抛出java.lang.InstantiationException异常。无法进行实例化。

3.克隆clone
JDK中Object# clone()方法的原型是:
protected native Object clone() throws CloneNotSupportedException;

方法修饰符是protected,而不是public。这种访问的不可见性使得我们对Object#clone()方法不可见。

所以,必需重写Object的clone方法后才能使用。

package cn.test;

 public class Student implements Cloneable {
 private String username;
 private String password;
 //重写clone方法
 public Object clone() throws CloneNotSupportedException {
 Student stu;
 stu = (Student) super.clone();
 return stu;
 }
 //类的空构造函数
 public Student() {
 }
 //类的带参数构造函数
 public Student(String username, String password) {
 this.username = username;
 this.password = password;
 }
 /**
 * get set 方法
 * 
 * */
 public String getUsername() {
 return username;
 }

 public void setUsername(String username) {
 this.username = username;
 }

 public String getPassword() {
 return password;
 }

 public void setPassword(String password) {
 this.password = password;
 }

 public static void main(String[] args) {
 Student student1 = new Student("aa", "11");
 /**
 * 克隆时必须捕获CloneNotSupportedException异常
 * */
 try {
 Student student2 = (Student) student1.clone();
 if (student1 != null) {
 System.out.println(student2);
 } else {
 System.out.println("Clone Not Supported");
 }
 } catch (CloneNotSupportedException c) {
 c.printStackTrace();
 }
 }

 }

4.序列化 Serializable
 序列化之前必须先实现类的Serializable接口
 同时序列化类
 private static final long serialVersionUID = 1L;
 测试代码
 java 
 因为序列化是输出输入流,所以要先抛出IO异常
 public static void main(String[] args)throws IOException {

 try {
 Student stu=new Student("aa","11");
 //创建一个对象输出流
 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:/obj.dat"));
 oos.writeObject(stu);
 oos.close();
 //创建一个对象输入流
 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/obj.dat"));
 Object obj=ois.readObject();
 Student stuBak=(Student)obj;
 //打印数据在控制台,检查序列化和反序列化是否成功
 System.out.println("stu name is: "+stuBak.getUsername());
 System.out.println("stu pass is: "+stuBak.getPassword());
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 }




5.使用Spring的DI
一、定义:Spring 是一个开源的控制反转(Inversion of Control,IoC/DI)和面向切面(AOP)的容器框架,它的主要目的是简化企业开发

二、实例化Spring容器:

方法一:在类路径下寻找配置文件来实例化容器

ApplicationContext ctx =

new ClassPathXmlApplicationContext(new String[]{“beans.xml”});

方法二:在文件系统路径下寻找配置文件来实例化容器

ApplicationContext ctx =

new FileSystemXmlApplicationContext(new String[]{“d:""beans.xml”});

注:文件可指定多个

可建立单元测试来测试Spring容器的初始化

public class ClassPathXmlApplicationContext implements BeanFactory {
 private HashMap<String,Object> beans = new HashMap<String,Object>();

 public ClassPathXmlApplicationContext() throws Exception{
 SAXBuilder sb = new SAXBuilder();
 Document dom = sb.build(TestJdom.class.getClassLoader().getResourceAsStream("beans.xml"));
 Element root = dom.getRootElement();
 List list = root.getChildren("bean");
 for(int i=0;i<list.size();i++){
 Element element = (Element) list.get(i);
 String id = element.getAttributeValue("id");
 String clazz = element.getAttributeValue("class");
 //利用Java反射机制,通过class的名称获取Class对象
 Object o = Class.forName(clazz).newInstance();
 System.out.println("o-->"+o.toString());
 System.out.println("o.getClass-->"+o.getClass())}
}

spring 的DI原理也是运用java的反射

===========================================================

简单的理解


package hellomyworld; public class Test { public Test() { System.out.println( " hello world " ); } }

此时在cmd下运行 javac Test.java就会产生一个Test.class的文件

另一个类Test2.class如何使用这个文件呢?

首先通知虚拟机从硬盘加载这个Test.class到内存中 Class testclass = Class.forName("hellomyworld.Test"); //test.Test代表路径
或者 Class testclass = hellomyworld.Test.class

testclass代表这个类的所有信息,注意他代表的是类的信息 不是类本身!

1 我想知道这个类叫什么? testclass.getName()
2 它有多少个方法呢?testclass.getDeclaredMethods()
3 它有多少个字段? testclass.getDeclaredFields()
以上的这3步就叫反射,当然还可以做更多的反射


然后告诉虚拟机初始化这个类 Object obj= testclass.newInstance(); 因为我先在想用了
Test test = (Test)obj;