在面向对象的思想中,一切事物均可以认为是对象——万物皆对象,把对象定义成包含状态和行为的一个实体,存在于现实世界中而且能够与其余实体区分开来的。对象具备状态和行为;好比:想一想你心仪的小姐姐,能够把这个小姐姐看做是一个对象,那么该对象有两方面的定义:状态和行为;状态,如身高,年龄,三围,头发(长发或者短发)等;行为,如调戏你、跳舞,玩手机等。java
经过多个相同类型的对象的状态和行为分析,能够把对象抽象成类(class);咱们把具备相同特性(状态)和行为(功能)的对象的抽象定义类,对象的抽象是类,类实例化后即是对象,类的实例是对象,类其实就是对象的数据类型,但其和基本数据类型的差别在于类是程序员为了解决某些问题而自定义的,基本数据类型是计算机中的数据存储单元。程序员
在Java中,对象的状态,用成员变量来描述;对象的行为,用方法来描述;故Java中类能够这样定义,语法以下:设计模式
类定义示例代码:数组
定义Java 类时有一些必要的规范须要遵照:jvm
先考虑下面的代码:函数
上述示例代码运行结果为:工具
为何会出现这样的结果呢?都是一样的值,为何会有不一样的比较结果?那是由于==和!=这两个比较运算符在比较基本数据类型和对象对象类型时是由区别的:性能
那么哪些数据类型时基本数据类型,哪些是引用数据类型呢?spa
因此,若是要对对象的值作比较,就必需要是用对象的equals()方法了;这里须要注意,equals()方法并不适用于基本数据类型,对于基本数据类型的变量来讲,使用== 和 !=足够了。下面用一个例子来实践,代码以下:操作系统
上述案例输出结果为:
由此可看出,使用对象的equals()方法是能正确比较对象的值的,由于Integer已经自定义了equals方法了,下面是源码:
不难发现,Integer的equals()方法的底层是使用基本数据类型的值作==比较的。若是是咱们自定义的类,并且没有从新定义equals()方法呢,结果又会是怎样的,一块儿来看看:
输出结果为:false。
由于在Java中,有一个全部引用类型都直接或者间接继承的父类,Object;所以,也能够说在java中,全部类都是Object的子类,那么,若是咱们没从新实现equals()方法,会默认调用Object的equals()方法,Object的equals()方法比较的是对象的引用,因此结果输出为false。
因此想要使用自定义对象的equals方法比较对象的值,那么就必须从新实现equals方法。
默认状况下,Java对象打印的效果是:类的名称@十六进制的hashCode,好比:
输出为:com.strlite.admin.demo.Value@79b4d0f,com.strlite.admin.demo.Value是类的名称,79b4d0f是一个十六进制的数,是对象在堆中的内存地址。
重写toString() 方法
能够经过重写toString() 方法来改变对象的打印效果:
输出为:
对象的开始:每次使用new关键字建立对象,就会在内存中开辟新的空间存储对象信息,此时对象开始存在。
对象的结束:当堆中的对象,没有被任何变量所引用,此时该对象就成了垃圾,等待垃圾回收器(GC)来回收;当对象被回收后,对象被销毁,对象占用的内存空间被释放,对象的生命周期结束。
对象建立以后没有将其赋给某一个变量。匿名对象只是在堆中开辟一块新的内存空间,可是没有把该空间地址赋给任何变量。由于没有变量引用指向,因此匿名对象仅仅只能使用一次,通常会把匿名对象做为方法的参数传递。
在建立对象时使用的特殊方法,出现new 关键字以后的方法,称之为构造方法、构造器、构造函数(Constructor)。
构造器的做用:
构造器的特色:
若是类中没有构造器,编译器会自动建立一个默认的无参构造器。
咱们将上述代码通过编译,获得字节码文件,再将字节码文件反编译,反编译的结果以下:
经过反编译后的结果,不难发现,即使咱们没有建立构造器,编译器也会为咱们建立一个默认的,编译器建立的默认构造器有如下的特色:
若是类中没有构造器,编译器会自动建立一个默认的无参构造器。可是,若是咱们显式地定义了一个构造器,则编译器再也不建立默认构造器。案例以下所示:
经过上述对比,不难发现,当类中存在一个构造器时,编译器便不会建立默认的构造器,而是使用咱们定义的构造器,由此可得出:在一个类中,至少存在一个构造器。
假如每一个人都有name和age两个状态,可是不一样人的name和age是不同的;也就说name和age是属于对象的。可是在生活中有些东西并非单单属于某一个对象的,而是属于整个类的,好比:每一个人都会老去、都会死。
因此,状态和行为的所属也应该有对象和类之分。 有的状态和行为应该属于对象,不一样的对象,状态和行为能够不同;而有的状态和行为应该属于类,不属于对象。为了区别与对象的状态和行为,引入static修饰符来修饰类的状态和行为。
static修饰符表示静态的,可修饰字段、方法、内部类,其修饰的成员属于类,static修饰的资源属于类级别,区别于对象级别。static的真正做用是用来区别字段、方法、内部类、初始化代码块是属于对象仍是属于类自己。
static修饰符的特色:
下面咱们经过一个案例来实践static关键字的使用:
static修改的变量称为常量,会长时间存在于JVM内存中,因此JVM也会为它分配必定的存储空间,如下即是static常量在jvm 中的内存模型:
JVM会将静态变量存储在方法区中,以便于及时调用;并保证其可以长时间存储于JVM中。
类中的成员:字段,方法,内部类。
通常状况下,类成员只能访问类成员,实例成员只能访问实例成员;但深究发现,对象其实能够访问类成员,可是底层依然使用类名访问的。
在static方法中,只能调用static成员;非static方法,能够访问静态成员,也能够访问实例成员;
那何时定义成static的字段和方法:
若是不使用static修饰,则这些方法属于该类的对象,咱们得先建立对象才能调用方法,在开发中工具对象只须要一份便可,可能建立N个对象,此时能够考虑使用单例设计模式。
好处:对对象的共享数据进行单独空间的存储,节省空间,没有必要每个对象中都存储一份,能够直接被类名调用。
弊端:生命周期过长。
局部变量定义后,必须显式初始化后才能使用,由于JVM不会为局部变量执行初始化操做。这就意味着,定义局部变量后,JVM并未为这个变量分配内存空间。直到程序为这个变量赋值时,系统才会为局部变量分配内存,并将初始值保存到该内存中。
局部变量不属于任何类或实例,所以它是保存在其所在方法的栈帧内存中。
栈帧内存中的变量随方法或代码块的运行结束而销毁,无须JVM回收。
完结。老夫虽不正经,但老夫一身的才华