第三章、万物皆对象

对象操纵

编程语言都会操纵内存中的元素,在C/C++中,对象的操纵是通过指针来完成的,Java是通过引用完成对象的操纵,个人认为Java的引用实际上就是阉割功能后比较安全的指针。
示例1:

String s;//创建了一个字符串对象引用s,这时直接使用会报错,因为s没有指向任何对象,常用做法是:创建一个引用的同时进行初始化
System.out.println(s.length());//执行报错,控制台打印:java: 可能尚未初始化变量s

示例2:

String s1 = new String("hello world1");
System.out.println(s1);  //控制台打印:hello world1
String s2 = "hello world2";
System.out.println(s2);  //控制台打印:hello world2

对象创建

通常可以使用new操作符创建对象,new关键字表示创建一个新的对象实例,如示例2所示。

数据存储

内存中5个地方可以存储数据

1.寄存器

最快的存储区域,位于cpu内部,但是数量有限,Java对其没有控制权,也无法在程序中找到寄存器存在的踪迹。

2.栈内存

存于常规内存RAM区域中,栈指针下移分配内存,上移释放内存,速度比寄存器慢,但是高于其他存储方式。Java程序要求必须准确知道栈内保存的所有项的生命周期,这种约束限制程序的灵活性。注:引用存在栈内存,对象存在堆内存。

3.堆内存

也存在RAM区域,是一种通用内存池,Java对象都存在堆内存中,Java不要求知道对象在堆内存的生命周期。清理和分配堆内存比栈内存需要更多时间。

4.常量存储

常量值一般直接写在程序代码中,永远不会变。

5.非RAM存储

数据完全存在于程序之外,在程序未运行以及脱离程序控制后依然存在。两个主要的例子:(1)序列化对象:对象被转换为字节流,通常被发送到另一台机器;(2)持久化对象:对象被放置在磁盘上,即使程序终止,数据依然存在。这些存储的方式都是将对象转存于另一个介质中,并在需要时恢复成常规的、基于 RAM 的对象。Java 为轻量级持久化提供了支持。而诸如 JDBC 和 Hibernate 这些类库为使用数据库存储和检索对象信息提供了更复杂的支持

基本类型的存储

基本数据类型不需要new来创建对象,可以直接赋值,这种变量都存放在栈空间中,常用的基本类型和C语言的变量类型基本相同。

基本类型大小最小值最大值包装类型
booleanBoolean
char16 bitsUnicode 0Unicode 216 -1Character
byte8 bits-128+127Byte
short16 bits- 215+ 215 -1Short
int32 bits- 231+ 231 -1Integer
long64 bits- 263+ 263 -1Long
float32 bitsIEEE754IEEE754Float
double64 bitsIEEE754IEEE754Double
voidVoid

基本类型都对应一个包装类型,拥有自动装箱和自动拆箱的特性,如下所示:
示例3:

char c1 = 'a';
Character c2 = c1;  //自动装箱,char类型转变为Character类型
Character c3 = 'b'; //自动装箱,char类型转变为Character类型
char c4 = c3;       //自动拆箱,Character类型转变为char类型

高精度数值

在 Java 中有两种类型的数据可用于高精度的计算。它们是 BigInteger 和 BigDecimal。BigInteger 支持任意精度的整数。可用于精确表示任意大小的整数值,同时在运算过程中不会丢失精度。 BigDecimal 支持任意精度的定点数字。例如,可用它进行精确的货币计算。这两个类提供的操作虽然可以保证精度,不过速度会下降,在交易系统中是否应该使用这两种类型有待商榷。

数组的存储

个人认为Java中有两种数据,分别为基本类型数组和对象数组。
基本类型数组在创建后如果不初始化,默认会将数组中的元素全部置为0;
创建对象数组时,实际上是创建了一个引用数组,并且每个引用的初始值都为 null 。在使用该数组之前,我们必须为每个引用指定一个对象 。如果我们尝试使用为 null 的引用,则会在运行时报错。因此,在 Java 中就防止了数组操作的常规错误。

对象清理

基本类型作用域

和在 C、 C++ 和相同,Java 中基本类型的作用域是由大括号 {} 的位置决定的。如下所示:
示例4:

{
    int a = 12;
    {
    	int a = 22;//非法,编译器会报错
        int b = 96;
        // a 和 b 变量皆可用
    }
    // 变量 b 不在作用域内,b不再可用
}
//变量a不在作用域内,a不再可用

对象作用域

Java 对象与基本类型具有不同的生命周期。使用 new 关键字来创建 Java 对象后,它的生命周期将会超出作用域。如下实例所示,引用s在}之后失效,没有主动回收s指向的对象,所对象依然存在于堆内存中,后续由垃圾收集器判断该对象不再被需要后才进行释放。
示例5:

{
    String s = new String("hello");
} 

类的创建

类型

Java使用 class 关键字类来描述一种新的对象。 通常在 class 关键字的后面的紧跟类的的名称。如下代码示例,引入了一个新的类型ATypeName,通过 new 关键字来创建一个这种类型的对象。
示例6:

class ATypeName {
 // 这里是类的内部
}
//创建对象
ATypeName a = new ATypeName();

字段/成员变量

类中存放两种元素:方法和字段,方法其实就是C/C++中的函数,字段大多数时候应该习惯叫做成员变量,个人更喜欢成员变量的叫法。成员变量可以是基本类型,也可以是引用类型,如下所示,
示例7:

class Student {
    int num;  //学号
    int age;  //年龄
    String name;//姓名
}

//创建学生对象
Student s = new Student();
//对成员变量进行赋值
s.num = 1;
s.age = 18;
s.name = "Tom";

如果成员变量是基本类型,则在类初始化时,这些成员变量会被赋予一个初始值,这些初始值对于程序来说并不一定是合法或者正确的,所以最好始终显式地初始化变量。

基本类型初始值
booleanfalse
char\u0000 (null)
byte(byte) 0
short(short) 0
int0
long0L
float0.0f
double0.0d

方法使用

Java中的方法就是C/C++中的函数,定义形式也和C/C++一样,如下所示。

 [返回类型] [方法名](/*参数列表*/){
     // 方法体
 }

调用对象方法的格式为:[对象引用].[方法名](参数1, 参数2, 参数3,…);
如下所示,在Student类中增加study函数,并进行函数调用。

示例8:

class Student {
    int num;
    int age;
    String name;
    void study(){
        System.out.println(name + "开始学习");
    }
}

//测试study方法
public static void main(String[] args) {
    Student s = new Student();
    s.name = "Tom";
    s.study();
}

//控制台打印结果:Tom开始学习

static关键字

类是对象的外观及行为方式的描述。通常只有在使用 new 创建那个类的对象后,数据存储空间才被分配,对象的方法才能供外界调用。这种方式在两种情况下是不足的。

  1. 有时你只想为特定字段(注:也称为属性、域)分配一个共享存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建对象。

  2. 创建一个与此类的任何对象无关的方法。也就是说,即使没有创建对象,也能调用该方法。

static 关键字(从 C++ 采用)就符合上述两点要求。当我们说某个事物是静态时,就意味着该字段或方法不依赖于任何特定的对象实例 。 即使我们从未创建过该类的对象,也可以调用其静态方法或访问其静态字段。相反,对于普通的非静态字段和方法,我们必须要先创建一个对象并使用该对象来访问字段或方法,因为非静态字段和方法必须与特定对象关联。static定义的东西都是类级别的,而非对象级别。但是对象也可以调用static声明的函数和变量,如下所示:

class Student {
    int num;
    int age;
    static String name; //静态函数不能调用非静态成员变量

    static void study(){
        System.out.println(name + "开始学习");
    }
}

//测试study方法
public static void main(String[] args) {
        
     //类名直接引用静态变量/方法是首选方法,强调了静态属性
  	 Student.name = "Tom";
     Student.study();

	 //创建对象后同样可以使用静态变量/方法
     Student s = new Student();
     s.name = "Lucy";
     s.study();
 }

控制台打印结果:
Tom开始学习
Lucy开始学习
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值