一、前言
Java中包括8种基本类型(9种包装类型,加一种Void)和3种引用类型(类、接口、数组,String是特殊的引用类型,enum枚举是特殊的类类型)。
二、基本类型与引用类型
2.1 基本类型
基本类型 | 对应的包装类型(引用类型) | 字节数 | 数值范围 | 默认值 |
---|---|---|---|---|
boolean | Boolean | ------ | ----------------- | false |
char | Character | 2字节 | Unicode 0~2^16-1 | ‘\u0000’(null) |
byte | Byte | 1字节 | -128~127 | (byte)0 |
short | Short | 2字节 | -2 ^ 15~2 ^ 15-1 | (short)0 |
int | Integer | 4字节 | -2 ^ 31~2 ^ 31-1 | 0 |
long | Long | 8字节 | -2 ^ 63~2 ^ 63-1 | 0L |
float | Float | 4字节 | IEEE754 | 0.0f |
double | Double | 8字节 | IEEE754 | 0.0d |
没有对应的基本类型 | Void | ------ | ------------------ | ------------ |
2.2 引用类型
Java有三种引用类型,类、接口、数组,默认值均为null,其中,枚举是特殊的类,String是特殊的引用类型。(此处注意:对于Java,主流观点是三种引用类型,类(包括枚举、String)、接口、数组;不过由于枚举和String的特殊性,也有四种引用类型的说法,类(包括String)、接口、数组、枚举的划分,本文采用主流说法,故三种引用类型)。
2.2.1 三种引用类型
引用类型 | 默认值 |
---|---|
类 | null |
接口 | null |
数组 | null |
空指针异常:空指针异常时开发中一个常见问题,因为引用类型默认初始值为null, 如果没有将其初始化就调用其方法或使用其属性,Java为防止程序崩溃,使用空指针异常提前阻止,类、接口、数组均有此问题。
代码1——类的空指针异常示意
package mypackage;
public class TestReferenceType {
public static void main(String[] args) {
A a = null;
// System.out.println(a._int); 访问其属性 空指针异常
// a.f1(); 调用其方法 空指针异常
}
}
class A {
public int _int;
public void f1() {
}
}
代码2——接口的空指针异常示意
package mypackage;
public class TestReferenceType {
public static void main(String[] args) {
A a = null;
// a.f1(); // 调用其方法 空指针异常
}
}
interface A {
void f1();
}
代码3——数组的空指针异常示意
package mypackage;
public class TestReferenceType {
public static void main(String[] args) {
Object[] _oObjects=null;
//System.out.println(_oObjects.length); //访问其属性 空指针异常
//_oObjects.hashCode(); //访问其属性 空指针异常
}
}
2.2.2 enum枚举(特殊的类类型)
Java中,JDK1.5引入枚举类型,枚举类型也是一种引用类型,可以看做是一种特殊的类。枚举类与普通类的相同和不同之处在于:
(1)枚举的定义和普通类的定义相似
class Gender{ //定义类
}
enum Sex{ //定义枚举
}
(2)编译后都生成.class后缀文件
(3)枚举类第一个语句是枚举值;普通类第一个语句无所谓。
(4)枚举类型中枚举值的默认修饰符是public static final,普通类类型中默认修饰符是default 非static 非final。
class Gender{ //定义类
String man,female; //访问类型默认为default,同包可见;非static,对象所有,对象调用;非final,可以修改;
}
enum Sex{ //定义枚举
MALE,FEMALE; //默认是 public static final Sex MALE=new Sex();
//public static final Sex FEMALE=new Sex();
//默认public,全局可见;static,枚举类所有;final,定义后不可修改;
}
(5) 枚举类型中枚举值默认值就是枚举值所属的类的对象;普通类中基本类型默认为对应初始值,引用类型默认为null。
class Gender{ //定义类
String man,female; //默认值为null
}
enum Sex{ //定义枚举
MALE,FEMALE; // public static final Sex MALE=new Sex(); 默认值为 new Sex()的引用
}
(6) 枚举类构造方法默认访问权限为private,仅本类可见;普通类构造方法默认访问权限为default,同包可见。
class Gender{ //定义类
String man,female; //默认值为null
Gender() { //默认为default,同包可见
}
}
enum Sex{ //定义枚举
MALE,FEMALE; // public static final Sex MALE=new Sex(); 默认值为 new Sex()的引用
Sex() { //默认为private,仅本类可见
}
}
(7)枚举类和普通类都要成员变量和成员函数。
class Gender{ //定义类
String man,female; //默认值为null
Gender() { //默认为default,同包可见
}
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
enum Sex{ //定义枚举
MALE,FEMALE; // public static final Sex MALE=new Sex(); 默认值为 new Sex()的引用
Sex() { //默认为private,仅本类可见
}
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
(8)都可以定义带参构造函数,且枚举类中枚举值可以指定使用何种构造函数。
(9) 枚举类和普通类中都可以定义抽象方法,但是枚举类中的抽象方法必须在枚举值中实现。
enum Sex{ //定义枚举
MALE{
void _run() {
System.out.println("The MALE is running");
}
},FEMALE{
void _run() {
System.out.println("The FEMALE is running");
}
},MAN("男"){
void _run() {
System.out.println("The MAN is running");
}
},WOMAN("女"){
void _run() {
System.out.println("The WOMAN is running");
}
};
Sex() { //默认为private,仅本类可见
}
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
Sex(String value){
this.value=value;
}
abstract void _run();
}
(10)完整代码——枚举类和普通类对比
package mypackage;
public class TestReferenceType {
public static void main(String[] args) {
//普通类
Gender gender = new ConcreteGender("CommonClass_male", "CommonClass_female");
gender._run();
System.out.println("=================================");
//枚举类
Sex.MALE.setValue("EnumClass_MALE");
Sex.MALE._run();
Sex.MALE.setValue("EnumClass_FEMALE");
Sex.FEMALE._run();
Sex.MALE.setValue("EnumClass_MAN");
Sex.MAN._run();
Sex.MALE.setValue("EnumClass_WOMAN");
Sex.WOMAN._run();
}
}
abstract class Gender { //定义类
String male, female; //默认值为null
Gender() { //默认为default,同包可见
}
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
Gender(String male, String female) {
this.male = male;
this.female = female;
}
abstract void _run();
}
class ConcreteGender extends Gender {
public ConcreteGender(String string, String string2) {
super(string, string2);
}
@Override
void _run() {
System.out.println(male + " is running");
System.out.println(female + " is running");
}
}
enum Sex { //定义枚举
MALE {
void _run() {
System.out.println("The " + value + " is running");
}
}, FEMALE {
void _run() {
System.out.println("The " + value + " is running");
}
}, MAN("男") {
void _run() {
System.out.println("The " + value + " is running");
}
}, WOMAN("女") {
void _run() {
System.out.println("The " + value + " is running");
}
};
Sex() { //默认为private,仅本类可见
}
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
Sex(String value) {
this.value = value;
}
abstract void _run();
}
输出:
CommonClass_male is running
CommonClass_female is running
=================================
The EnumClass_MALE is running
The null is running
The 男 is running
The 女 is running
2.2.3 String(特殊的引用类型)
String是特殊的引用类型,Java中String被当做对象处理,我个人更倾向于将它划入引用类型的类类型中。关于String的特殊之处:
(1)String是一个不可变对象,修改String引用的值实际上是新建了一个String对象。
String s = "China";
s = "Beijing";
小结:
前半句,String是一个不可变对象:此处s仅仅是一个引用,不是String对象,“China"这个字符串对象并没有变成"Beijing"字符串。而仅仅是字符串引用s指向了一个新的字符串对象"Beijing”,旧的字符串对象"China"仍然存在,并且没有任何改变(注意:可变字符串是StringBuffer、StringBuilder,相对复杂,此处不展开讨论)。
后半句,修改String引用的值实际上是新建了一个String对象:此处表面上看是修改了字符串引用s的值,但是因为字符串不可变(前半句),所以此处并不是修改值,而是新建一个“Beijing”字符串,然后让字符串引用s指向它。
(2)两种创建方式
String s1=new String("abc");
String s2="abc";
(3)String的比较
关于s1与s2的是否相等(equals和==),请参考Java常量池知识,此处不展开讨论。
(4)String的传参
Java中参数传递方式只有按值传递一种方式,Java中有引用,但是请记住,“有引用和有引用传递是两个概念”,Java中没有引用传递。所以String也是值传递,但是它的值传递相对于基本类型有所不同。String是将字符串传递给实参,由于String是不可变对象,实参的修改不影响形参。
三、尾声
Java中的数据类型包括8种基本类型和3种引用类型(类(包括枚举、String)、接口、数组),正确理解Java数据类型是Java学习最基础的一步,为后期学习打下扎实的基础。
天天打码,天天进步!!!