【学习笔记】Java中生成对象的5中方法

概述:本文介绍以下java五种创建对象的方式:

1.用new语句创建对象,这是最常用的创建对象的方式。

2.使用Class类的newInstance方法

3.运用反射手段,调用java.lang.reflect.Constructor类的newInstance()实例方法。

4.调用对象的clone()方法。

5.运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.

一、使用new关键字

  这是最常见也是最简单的创建对象的方式了。通过这种方式,我们可以调用任意的构造函数(无参的和带参数的)。

二、使用Class类的newInstance方法

  使用Class类的newInstance方法创建对象。这个newInstance方法调用无参的构造函数创建对象。

三、使用Constructor类的newInstance方法

  和Class类的newInstance方法很像, java.lang.reflect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数的和私有的构造函数。

  newInstance方法内部调用Constructor的newInstance方法。这也是众多框架,如Spring、Hibernate、Struts等使用后者的原因。

四、使用clone方法

  无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

要使用clone方法,我们需要先实现Cloneable接口并实现其定义的clone方法。

 1 public class Customer implements Cloneable{
 2 private String name;
 3 private int age;
 4 public Customer(){
 5   this("unknown",0);
 6   System.out.println("call default constructor");
 7 }
 8 public Customer(String name,int age){
 9   this.name=name;
10   this.age=age;
11   System.out.println("call second constructor");
12 }
13 public Object clone()throws CloneNotSupportedException{
14 return super.clone();
15 }
16 public boolean equals(Object o){
17   if(this==o)return true;
18   if(! (o instanceof Customer)) return false;
19   final Customer other=(Customer)o;
20   if(this.name.equals(other.name) && this.age==other.age)
21      return true;
22   else
23      return false;
24 }
25 public String toString(){
26 return "name="+name+",age="+age;
27 }
28 public static void main(String args[])throws Exception{
29 //运用反射手段创建Customer对象
30 Class objClass=Class.forName("Customer");
31 Customer c1=(Customer)objClass.newInstance(); //会调用Customer类的默认构造方法
32 System.out.println("c1: "+c1); //打印name=unknown,age=0
33
34 //用new语句创建Customer对象
35 Customer c2=new Customer("Tom",20);
36 System.out.println("c2: "+c2); //打印name=tom,age=20
37
38 //运用克隆手段创建Customer对象
39 Customer c3=(Customer)c2.clone(); //不会调用Customer类的构造方法
40 System.out.println("c2==c3 : "+(c2==c3)); //打印false
41 System.out.println("c2.equals(c3) : "+c2.equals(c3)); //打印true
42 System.out.println("c3: "+c3); //打印name=tom,age=20
43 }
44 }  

五、使用反序列化

  当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造函数。

为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp = (Employee) in.readObject();

注意:除了第1个方法,其他4个方法全都转变为invokevirtual(创建对象的直接方法),第一个方法转变为两个调用,new和invokespecial(构造函数调用)。

除了以上5种显式地创建对象的方式以外,在程序中还可以隐含地创建对象,包括以下几种情况:

1.对于java命令中的每个命令行参数,Java虚拟机都会创建相应的String对象,并把它们组织到一个String数组中,再把该数组作为参数传给程序入口main(String args[])方法。

2.程序代码中的String类型的直接数对应一个String对象,例如:

  1. String s1="Hello";
  2. String s2="Hello"; //s2和s1引用同一个String对象
  3. String s3=new String("Hello");
  4. System.out.println(s1==s2); //打印true
  5. System.out.println(s1==s3); //打印false

执行完以上程序,内存中实际上只有两个String对象,一个是直接数,由Java虚拟机隐含地创建,还有一个通过new语句显式地创建。

3.字符串操作符“+”的运算结果为一个新的String对象。例如:

  1. String s1="H";
  2. String s2=" ello";
  3. String s3=s1+s2; //s3引用一个新的String对象
  4. System.out.println(s3=="Hello"); //打印false
  5. System.out.println(s3.equals("Hello")); //打印true

4.当Java虚拟机加载一个类时,会隐含地创建描述这个类的Class实例.

参考资料:

java中生成对象的方式有多种,如下所示:

1、使用new操作符,这是最普遍的一种

如:String s=new String("abc");

2、使用反射动态生成

利用Class,ClassLoader,Constructor中的方法可以动态的生成类实例

如:Object o=Class.forName("java.lang.String").newInstance();

Object o=String.class.getClassLoader.loadClass("java.lang.String").newInstance();

以上的方式需要目标类拥有公有无参构造函数

以下使用Constructor进行动态生成

class User{

public User(String user,Integer id){}

}

Constructor c=User.class.getConstructor(new Class[]{String.class,Integer.class});

User user=(User)c.newInstance(new Object[]{"zhang san",123});

3、使用克隆生成对象

例如使用一个实现了Cloneable接口的对象,调用其clone()方法获得该对象的一份拷贝

4、利用反序列化从流中生成对象

利用ObjectInptuStream的readObject()方法生成对象

时间: 2024-08-05 11:11:04

【学习笔记】Java中生成对象的5中方法的相关文章

学习笔记——Java类和对象

今天学习了Java的类和对象的相关知识,由于Java面向对象的编程的思想和C++几乎一样,所以需要更多的关注Java的一些不同之处. 1.类 1.1 在类这一块,除了基本的成员变量,成员方法,构造函数等外,需要掌握三种权限修饰符的区别,并会合理使用(private限制了权限只在本类,protected限定了权限只在包内). 1.2 静态常量.变量.方法:static修饰.我们可以使用“类名.静态类成员”来调用,如: public class StaticTest{ static double P

【Thinking In Java零散笔记】对于持有对象一章中的显示系统环境变量代码分析

今天仍旧进行着学习java的计划.在学习到持有对象一章中,看到了如下代码: 1 import java.util.*; 2 3 public class EnvironmentVariables { 4 public static void main(String[] args) { 5 for(Map.Entry entry: System.getenv().entrySet()) { 6 System.out.println(entry.getKey() + ": " + 7 en

angular学习笔记(二十八-附2)-$resource中的promise对象

下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource){ return $resource('/card/user/:userID/:id',{userID:123,id:'@id'},{charge:{method:'POST',params:{charge:true},isArray:false}}) }); HttpREST.factory('h

疯狂Java学习笔记(56)------------对象序列化

所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象! 对象序列化是对象持久化的一种实现方法,它是将一个对象的属性和方法转化为一种序列化的格式以用于存储和传输,反序列化就是根据这些保存的信息重建对象的过程. java对象序列化机制一般来讲有两种用途: 1.需要将对象的状态保存到文件中(存储),而后能够通过读入对象状态来重新构造对象,恢复程序状态 2.使用套接字在网络上传送对象的程序来说,是很有用的(传输). 我们通过让类实现java.io.Serializable

android学习笔记——利用BaseAdapter生成40个列表项

RT: main.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               android:orientation="vertical"        

Java程序猿的JavaScript学习笔记(5——prototype和Object内置方法)

计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript学习笔记(3--this/call/apply) Java程序猿的JavaScript学习笔记(4--this/闭包/getter/setter) Java程序猿的JavaScript学习笔记(5--prototype) Java程序猿的JavaScript学习笔记(6--面向对象模拟) Java程

Effective Java读书笔记(3对于所有对象都通用的方法)

3.1 覆盖equals时请遵守通用约定 什么时候应该覆盖Object.equals()方法呢? 如果类具有自己特有的"逻辑相等"概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法. Object.equals()方法具有自反性.对称性.传递性.一致性和与null比较返回false的特点. 实现高质量equals方法的诀窍: (1)使用==操作符检查"参数是否为这个对象的引用".如果是,则返回true,这

struts2学习笔记(三)—— 在用户注册程序中使用验证框架

实现目标: 1.使用验证框架对用户注册信息进行验证 2.验证用户名.密码.邮箱不能为空 3.验证用户名.密码长度 4.验证邮件地址格式 具体实现 一.Struts2应用的基础配置 这里不做详细阐述,具体为web.xml.相关jar包的配置 二.将页面显示的文本内容放到资源文件中 1.查看用户注册程序中的所有页面,找到所有可以显示的文本内容,将它们分离出来放到资源文件中. 2.与相关的Action类同名,以.preperties为扩展名,与Action类位于同一个包中,只能由该Action访问 R

JS学习笔记-OO疑问之对象创建

问一.引入工厂,解决重复代码 前面已经提到,JS中创建对象的方法,不难发现,基本的创建方法中,创建一个对象还算简单,如果创建多个类似的对象的话就会产生大量重复的代码. 解决:工厂模式方法(添加一个专门创建对象的方法,传入参数避免重复) function createObject(name,age){ var obj =new Object(); //创建对象 obj.name = name; obj.age = age; obj.run = function(){ return this.nam