一、创建对象的几种方式
其实对象的初始化就是在创建对象的时候由jvm完成的。对于创建对象,主要是研究创建对象的几种方式。下面一一的解答.这里给出6种方式,面试的时候足够了。但目前掌握第一种就够用了。
1.使用new关键字
2.Class对象的newInstance()方法
3.构造函数对象的newInstance()方法
4.对象反序列化
5.Object对象的clone()方法
6.使用Unsafe类创建对象
(1)使用new关键字
创建一个对象包含下面两个过程:
1、类构造器完成类初始化(分配内存、赋予默认值)
2、类实例化(赋予给定值)
Test1完成1、2步骤 但是2实例化赋值为空
Test2完成1、2步骤 赋值为java的。。。。
(2)class的newInstance()方法
首先我们通过Class.forName()动态的加载类的Class对象,
然后通过newInstance()方法获得Test类的对象
(3)构造函数的newInstance()方法
类Constructor也有newInstance方法,这一点和Class有点像。从它的名字可以看出它与Class的不同,Class是通过类来创建对象,而Constructor则是通过构造器。(4)序列化
首先我们要对Test实现Serializable接口。然后开始序列化数据。最后得到反序列化的对象。
(5)clone方式
Object对象中存在clone方法,它的作用是创建一个对象的副本。
(6)使用Unsafe类创建对象
Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力,同时也带来了指针的问题。过度的使用Unsafe类会使得出错的几率变大,因此Java官方并不建议使用的,官方文档也几乎没有。Oracle正在计划从Java 9中去掉Unsafe类,如果真是如此影响就太大了。
我们无法直接创建Unsafe对象。这里我们使用反射方法得到
拿到这个对象后,调用其中的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允许在一个类中定义多个名称相同的方法,但是参数的类型或个数必须不同,这就是方法的重载。
下面的三个方法互为重载关系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