美文网首页
JAVA 入门笔记-包装类型

JAVA 入门笔记-包装类型

作者: Alaricming | 来源:发表于2020-02-15 11:28 被阅读0次

一,包装类型

  • 基本类型: byte , short,int,long,boolean,float,double,char
  • 引用类型:所有的classinterfere 类型

引用类型可以赋值为 null, 表示空,但是基本类型不能赋值为 null

基本类型转换为引用类型
// Integer 作为 int 的包装类
public Integer {
  private int value;
  
  public Integer(int value) {
    this.value = value;
  }
  
  public int intValue() {
    return this.value
  }
}

// 定义好了,就可以像下面这样转换
Integer n = null;   // 引用类型可以赋值为 null
Integer n2 = new Integer(1); // 实例化时调用构造函数 Integer
int n3 = n2.intValue();   // 取值

在 java 核心库里面,每个基本类型都有对应的包装类型。

public class Main {
  public static void main(String[] args) {
    Integer n1 = new Integer(1);  // 不推荐使用,会有编译警告
    Integer n2 = Integer.valueOf(2);   // 静态方法 Integer.valueOf(int) 创建
    Integer n3 = Integer.valueOf("3");   // 静态方法 Integer.valueOf(String) 创建
  }
}
auto boxing

因为intInteger之间可以互相转换

int i = 100;
Integer n = Integer.valueOf(i);
int m = n.intValue();

所以java编译器会帮助我们自动在 intInteger之间转换

Integer n = 100;  // 编译器自动调用Integer.valueOf(int)
int x = n;        // 编译器自动调用Integer.intValue();

这种行为叫自动装箱(auto boxing)自动拆箱(auto unboxing),只发生在编译阶段,目的是减少代码量

不变类

所有的包装类都是不变类

// 修饰类当用final去修饰一个类的时候,表示这个类不能被继承。
// 注意:a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。
//      b. final类中的成员方法都会被隐式的指定为final方法
public final class Integer {
  private final int value;
}

不能用==来比较Integer大小,因为它是引用类型,必须使用 equals() 比较

?????

对于较小的相同大小Integer==比较会返回 true, ==较大的两个相同的Integer返回false,这是因为Integer是不变类,编译器把Integer x = 127;自动变为Integer x = Integer.valueOf(127);,为了节省内存,Integer.valueOf()对于较小的数,始终返回相同的实例,因此,==比较“恰好”为true,但我们绝不能因为Java标准库的Integer内部有缓存优化就用==比较,必须用equals()方法比较两个Integer。==

进制转换

Integer 类提供了大量方法,最常用的静态方法parseInt()可以把字符串解析成一个整数

int x1 = Integer.parseInt("100");   // 100;
int x2 = Integer.parseInt("100", 16) // 256,16进制

需要注意的是:在计算机内存中,只用二进制表示数据,而基于显示数据的存储和显示分离的思想可以想到,System.out.println(n);这样的打印操作只是核心库将数据转换为十进制输出到屏幕上。

二,JavaBean

JavaBean 是一种符合命名规范的class, 通过 setter,getter 来定义和读取属性

import java.beans.*;

public class Main{
  public static void main(String[] args) throw Exception{
    var p = new Person();
    
    p.setName("wow");
    
    // person.class 是从 object 继承的 getClass() 方法带来的
    BeanInfo info = Introspector.getBeanInfo(Person.class);
    // Introspector.getBeanInfo() 可以读取属性列表
    for(PropertyDescriptor pd : info.getPropertyDescriptors()) {
      System.out.println(pd.getName());
      System.out.println("  " + pd.getReadMethod());
      System.out.println("  " + pd.getWriteMethod());
    }
  }
}

class Person {
  private String name;
  private int age;
  
  // setter and getter
  public String getName(){
    return this.name
  }
  public void setName(String name) {
    this.name = name;
  }
}

四,枚举类

java中,可以通过static final 来定义常量

public class WeekDay {
  public static final int SUN = 0;
  public static final int MON = 0;
  // ...
}

关于java 中的静态变量和非静态变量

  • 一种被static变量修饰的变量,叫类变量或者静态变量;一种是没有 static 修饰的,叫成员变量

  • 通俗的讲,类的静态变量在内存中只有一个,java 虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以通过类名进行访问,其生命周期取决于类的生命周期

    实例变量取决于类的实例,每创建一个实例,java 虚拟机就会为实例变量分配一次内存,实例变量位于堆栈中,其生命周期取决于实例的生命周期

由上述可知,访问静态变量的方式为:WeekDay.SUM

enum

上述方式使用常量来表示一组枚举值时会存在一个问题:编译器无法检测某个值的合理性。而为了让编译器能自动检测到某个值是否在枚举值的范围内,并且对于不同的枚举类需要用不同的类型标记,我们可以使用enum 来定义枚举类

public class Main {
  public static void main(String[] args) {
    WeekDay day = WeekDay.SUN;
    
    if(day == WeekDay.SUN || day == WeekDay.SAT) {
      System.out.println("放假啦 !")
    }
  }
}

enum WeekDay {SUN, MON, TUE, WED, THU, FRI, SAT;}

注意:

  • 只需要列举常量名,enum 会自动初始化他们的值

  • Enum 定义的常量自带类型信息,编译器能自动检测类型错误

    int day = 1;
    if(day == WeekDay.SUN) {   // Compile error: bad operand types for binary operator '=='
        // ...
    }
    
  • 不同枚举类型之间不能互相赋值

    WeekDay x = WeekDay.SUN;  // ok!!
    WeekDay y = Color.RED;    // compile error: inconpatible types
    
enum 的比较

枚举类是引用类型,按照一般理解,引用类型要用 equals() 来比较,而使用 == 判断时,比较的是两个引用类型是否指代同一个对象。但是enum 的比较是个例外。

if(day == W eekDay.SUN) { //...}      // ok !
if(day.equals(WeekDay.SUN)) { //...}  // still ok, but more code !
enum 类型

enum 本质就是 class, 只是有一些自己的特性

  • 定义的 enum 类型始终继承自java.ang.Enum, 并且无法被继承;
  • 只能定义 Enum 的实例,而无法通过 new 创建实例;
  • 定义的每个实例都是引用类型的唯一实例;
  • 可以将enum类型用于switch语句
public enum Color {
  RED, GREEN, BLUE;
}

// 编译器编译出来的大概是这样:
public class Color extends Enum {                    // 继承自`java.lang.Enum`
  public static final Color RED = new Color();       // 静态常量
  public static final Color GREEN = new Color();
  public static final Color BLUE = new Color();
  
  private Color() {        // 构造函数用 private 修饰,确保外部不能用 new 操作符创建实例
    // ...
  }
}

其实 enum 跟普通 class没有任何区别,只是 java 语法规定必须使用 enum 关键字

相关文章

网友评论

      本文标题:JAVA 入门笔记-包装类型

      本文链接:https://www.haomeiwen.com/subject/ttyefhtx.html