语法基础(四. 引用数据类型,对象的几种创建方式,匿名对象)
(如有错误,欢迎指正,感谢!)
引用数据类型
引用数据类型大致包括
-
类
-
接口类型
-
数组类型
-
字符串类型
-
枚举类型
-
注解类型
-
在创建一个对象时,new的主要功能就是分配内存空间
-
在堆内存中开辟一块空间,用来代表某一个类对象,这个对象在内存中有一个地址,而引用数据类型的变量就是专门存储该地址的,通过这个地址能够找到这个对象的信息。
new出来的叫对象,引用类型变量只是引用了对象地址
System.out.println(new int[10]); // [I@2d98a335 int[] arr=null; arr=new int[10]; System.out.println(arr); //[I@16b98e56
参数传递方面的区别
-
引用类型是引用传递
-
基本类型是值传递
对象
-
类定义完成之后,无法直接使用,如果要使用,必须依靠对象
-
对象是对类的实例化。对象具有状态和行为,变量代表状态,方法代表行为
创建对象一般需要以下三步:
-
声明:声明一个对象,包括对象名称和对象类型。
-
实例化:使用关键字new来创建一个对象,(通过类名创建相应对象)
-
初始化:使用new创建对象时,会默认调用相应构造方法初始化对象。
对象的几种创建方式(实例化)
一. 显式创建
(1)使用 new 关键字创建对象
类名 对象名 = null; // 1. 先声明
对象名 = new 类名(); // 再创建对象
类名 对象名 = new 类名(); // 2. 一步创建,声明的同时创建
(2)反射机制创建
1. 调用java.lang.Class 或者java.lang.reflect.Constuctor类的~~newlnstance()~~方法创建(Java 9 之后过时)
Class Class对象名 = Class.forName("包名.类名");
类名 对象名 = (类名) Class对象名.newInstance();
类名 对象名 = (类名)Class.forName("包名.类名").newInstance(); //一步创建
-
该方法在Java 9之后已经过时
-
替代方法为 :
clazz.getDeclaredConstructor().newInstance()
Class Class对象名 = Class.forName("包名.类名");
类名 对象名 = (类名) Class对象名.getDeclaredConstructor().newInstance();
//一步创建
类名 对象名 = (类名)Class.forName("包名.类名").getDeclaredConstructor().newInstance();
2. 使用Constructor类中的newInstance()方法
Class Class对象名 = Class.forName("包名.类名");
Constructor Constructor对象名 = Class对象名.getConstructor();
类名 对象名 = (类名) Constructor对象名.newInstance();
//一步创建
类名 对象名 = (类名)Class.forName("包名.类名").getConstructor().newInstance();
(3)采用序列化机制
调用 java.io.ObjectlnputStream 对象的 readObject() 方法
(4)调用对象的clone()方法,使用该方法时,该对象所属的类,必须实现了Cloneable接口
类名 对象名 = (类名)已创建好的该类的对象名.clone();
clone创建对象注意事项:
-
clone(复制)用于拷贝对象,一种浅拷贝
-
基本数据类型只要把数值复制过来就行
-
对于引用数据类型,是一个引用,指向对象的地址,拷贝时,地址也会被复制过去。
-
这样导致两个对象中,引用类型中的数据还是公用一个对象,一旦有一个对象将引用类型中的数据改变,另一个对象中的内容也会随着改变
显式创建总结:
使用 new 关键字或 Class 对象的 newInstance() 方法创建对象时,都会调用类的构造方法。
使用 Class 类的 newInstance() 方法创建对象时,会调用类的默认构造方法,即无参构造方法。
使用 Object 类的 clone() 方法创建对象时,不会调用类的构造方法,它会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但它们的属性值相同。
二. 隐含创建
-
对于
String name="zjl"
,就会默认创建一个String类型对象,等价于String str=new String("zjl")
-
“+”,作为连接运算符时,将数据连接后结果是一个新的String对象
int num=78; String string = new String("zjl"+123456+num);
-
当 Java 虚拟机加载一个类时,会隐含地创建描述这个类的 Class 实例。
类的加载: 指把类的 .class 文件中的二进制数据读入内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。
创建对象时都会:
- 给对象分配内存。
- 将对象的成员变量自动初始化为对应类型的默认值。
- 初始化对象,给成员变量赋予相应的初始值,(通过构造方法)
匿名对象
-
创建对象时,只有创建对象的语句,却没有把对象地址赋值给某个引用类型变量,
-
也就是说匿名对象是没有变量名的对象,只new了一个对象,并没有用变量存储这个对象(对象没名字)
**语法格式: ** new 类名(参数列表);
用法
-
使用匿名对象,直接调用成员方法,成员变量
int num = new Random().nextInt();
-
匿名对象作为方法参数,返回值
public static void main(String[] args){ //通过匿名对象传入Random类型参数 putNum(new Random()); //匿名对象作为返回值返回 Random random=getRandom(); System.out.println(random.nextInt()); } public static void putNum(Random random){ System.out.println(random.nextInt()); } //匿名对象作为返回值返回 public static int getRandom(){ return new Random(); }
匿名对象注意事项
- 每次创建匿名对象,只能使用一次,用完之后直接被释放,每次new都相当于重新创建了一个对象
public class A{
public String name;
public void putName(){
System.out.println(name);
}
public static void main(){
new A().name="zjl"; //使用完,直接被释放
new A().putName(); //使用完,直接被释放
}
}
结果为: null
因为每次匿名对象使用完都被释放,new都相当于重新创建了一个对象
- 静态存储区(共享区)中的内容,所有对象共享,不会随着类的释放而消失
public class A{
public static String name; //将name声明为static的
public void putName(){
System.out.println(name);
}
public static void main(){
new A().name="zjl"; //使用完,直接被释放,但是name中的内容不会随着类的释放而消失
new A().putName(); //使用完,直接被释放
}
}
结果为: zjl
静态存储区的内容所有对象所共享,不会随着类的释放而消失
( 注:部分资料参考网络,如有侵权请联系。)