一、创建对象的几种方式

其实对象的初始化就是在创建对象的时候由jvm完成的。对于创建对象,主要是研究创建对象的几种方式。下面一一的解答.这里给出6种方式,面试的时候足够了。但目前掌握第一种就够用了。

1.使用new关键字
2.Class对象的newInstance()方法
3.构造函数对象的newInstance()方法
4.对象反序列化
5.Object对象的clone()方法
6.使用Unsafe类创建对象

(1)使用new关键字

java new两个相同的对象 java重复new对象_构造方法


创建一个对象包含下面两个过程:

1、类构造器完成类初始化(分配内存、赋予默认值)

2、类实例化(赋予给定值)

Test1完成1、2步骤 但是2实例化赋值为空

Test2完成1、2步骤 赋值为java的。。。。

(2)class的newInstance()方法

java new两个相同的对象 java重复new对象_System_02


首先我们通过Class.forName()动态的加载类的Class对象,

然后通过newInstance()方法获得Test类的对象

(3)构造函数的newInstance()方法

java new两个相同的对象 java重复new对象_Code_03


类Constructor也有newInstance方法,这一点和Class有点像。从它的名字可以看出它与Class的不同,Class是通过类来创建对象,而Constructor则是通过构造器。(4)序列化

java new两个相同的对象 java重复new对象_System_04


首先我们要对Test实现Serializable接口。然后开始序列化数据。最后得到反序列化的对象。

(5)clone方式

Object对象中存在clone方法,它的作用是创建一个对象的副本。

java new两个相同的对象 java重复new对象_Code_05


(6)使用Unsafe类创建对象

Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力,同时也带来了指针的问题。过度的使用Unsafe类会使得出错的几率变大,因此Java官方并不建议使用的,官方文档也几乎没有。Oracle正在计划从Java 9中去掉Unsafe类,如果真是如此影响就太大了。

我们无法直接创建Unsafe对象。这里我们使用反射方法得到

java new两个相同的对象 java重复new对象_System_06


拿到这个对象后,调用其中的native方法allocateInstance 创建一个对象实例

Object event = unsafe.allocateInstance(Test.class);

二、方法的定义和调用
public class MethodDemo01 { //public定义类
public static void main(String[] args) { //方法的具体语法格式,此处为构造方法,无返回值
int area = getArea(3, 5); // 调用 getArea方法 3*5
System.out.println(" The area is " + area);
}

// 下面定义了一个求矩形面积的方法,接收两个参数,其中x为高,y为宽
public static int getArea(int x, int y) {    //成员方法,返回值为int型
	int **temp** = x * y;    // 使用变量temp记住运算结果
	return **temp**;    // 将变量temp的值返回  
}

}

结果为:

java new两个相同的对象 java重复new对象_构造方法_07


三、方法的重载

Java允许在一个类中定义多个名称相同的方法,但是参数的类型或个数必须不同,这就是方法的重载。
 下面的三个方法互为重载关系public static int add(int x,int y) {逻辑} //两个整数加法
public static int add(int x,int y,int z) {逻辑} //三个整数加法
public static double add(double x,double y) {逻辑} //两个小数加法
通过方法重载方式进行修改之后代码如下:public class MethodDemo03 {
 public static void main(String[] args) {
 // 下面是针对求和方法的调用
 int sum1 = add(1, 2);
 int sum2 = add(1, 2, 3);
 double sum3 = add(1.2, 2.3);
 // 下面的代码是打印求和的结果
 System.out.println(“sum1=” + sum1);
 System.out.println(“sum2=” + sum2);
 System.out.println(“sum3=” + sum3);
 }// 下面的方法实现了两个整数相加
**public static int add(int x, int y) {
	return x + y;**
}
// 下面的方法实现了三个整数相加
**public static int add(int x, int y, int z) {
	return x + y + z;**
}
// 下面的方法实现了两个小数相加
**public static double add(double x, double y) {
	return x + y;**
}}
 运行结果与前一个代码运行结果相同。

方法的重载与返回值类型无关,它只有两个条件,一是方法名相同,二是参数个数或参数类型不相同。

四、方法覆盖:

方法覆盖: 父类和子类有相同的方法和参数
 public class Parent{ //父类Parent
 public void test(){
 System.out.println(“这是父类方法”)
 }
 }
 public class Children extends Parent{ //子类Children
 public void test(){
 System.out.println(“这是子类方法”)
 }
 }

结果:这是子类方法

构造方法
作用:构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。
格式: 方法的名字必须和类的名字完全一致。构造方法不允许写返回值类型,void也不能写。命名格式如下

public 类名称(参数类型 参数名称) {
 方法体
 }
 构造方法的使用——用个例子来体会
 Person类
 public class Person {
 private String name;
 private int age;//定义Person类的构造方法
public Person(){
	System.out.println("我是一个空参数的构造方法");
}}
 Test测试类
 public class Test {
 public static void main(String[] args) {
 Person p = new Person();
 }
 }
 打印出来的是这样的~我是一个空参数的构造方法
 如何给构造方法赋值
 person类
 public class Person {
 private String name;
 private int age;
 //定义Person类的构造方法
 public Person(String name,int age){
 this.name = name;
 this.age = age;
 }
 public String getName() {
 return name;
 }public void setName(String name) {
	this.name = name;
}

public int getAge() {
	return age;
}

public void setAge(int age) {
	this.age = age;
}}
 Test类
 public class Test {
 public static void main(String[] args) {
 Person p = new Person(“张三”,20);
 //对象p调用方法getName,geAge
 System.out.println(p.getName());
 System.out.println(p.getAge());
 }
 }
 结果:张三
 20
 构造方法和一般方法的区别
 从定义上看:
 构造方法的名字必须有固定的格式,不能更改(格式要求在上文)。而其他方法名字可以自己定义,可以有void等等。
 从执行上看:
 构造方法在对象创建时就已经执行了,而且只执行一次。其他方法可以自己手动调用,想调用几次就调用几次。
 [java] view plain copy
 class Code {
 {
 System.out.println(“Code的构造块”);
 }
 static {
 System.out.println(“Code的静态代码块”);
 }
 public Code() {
 System.out.println(“Code的构造方法”);
 }
 }
 public class CodeBlock03 {
 {
 System.out.println(“CodeBlock03的构造块”);
 }
 static {
 System.out.println(“CodeBlock03的静态代码块”);
 }
 public CodeBlock03() {
 System.out.println(“CodeBlock03的构造方法”);
 }
 public static void main(String[] args) {
 System.out.println(“CodeBlock03的main方法”);
 new Code();
 new CodeBlock03();
 }
 }
 /* 运行结果:
 CodeBlock03的静态代码块
 CodeBlock03的main方法
 Code的静态代码块
 Code的构造块
 Code的构造方法
 CodeBlock03的构造块
 CodeBlock03的构造方法*/package com.Mubai;public class ThisDemo {
 private String name;
 ThisDemo() {
 System.out.println(“我是无参构造方法”);
 }
 ThisDemo(String name) {
 //用于构造函数间的相互调用,而且只能放在构造函数的第一行
 this();//表示调用本类中的无参构造方法
 //如果在构造方法里使用(name=name) ,那么其是赋值给他本身,而不是赋值给类里面的属性name。
 this.name = name; // this.name=p1.name:
 //这里写这p1是因为p1这个对象在调用这个函数。一句话,谁调用它就在代表谁。
 this.method(); //其实就==p1.method
 }
 public void method() {
 System.out.println(“我是构造方法”);
 }
 public static void main(String[] args) {
 ThisDemo p1 = new ThisDemo(“Mubai”);
 System.out.println(p1.name);}}
//运行结果:
 我是无参构造方法
 我是构造方法
 Mubai