Kingdee : Quels sont les types de données de base en Java ? Comprenez-vous la technologie de la piscine constante de type wrapper?

Bonjour, je m'appelle Guide. Partagez quelques vraies questions d'entretien de base sur Java rencontrées par des amis du groupe lors de l'entretien avec Kingdee :

  • "Connaissez-vous plusieurs types de données de base en Java ?".
  • Différence entre le type primitif et le type wrapper ?
  • Comprenez-vous la technologie de la piscine constante de type wrapper?
  • Comprenez-vous l'autoboxing et l'unboxing ? C'est quoi le principe ?

Connaissez-vous plusieurs types de données de base en Java ?

Il existe 8 types de données de base en Java, ce sont :

  • 6 types numériques :
    • 4 types entiers : byte, short, int,long
    • 2 types de virgule flottante : float,double
  • 1 type de caractère :char
  • 1 booléen : boolean.

Les valeurs par défaut de ces 8 types de données de base et la taille de l'espace occupé sont les suivantes :

type de base nombre de chiffres octet Valeurs par défaut Gammes
byte 8 1 0 -128 ~ 127
short 16 2 0 -32768 ~ 32767
int 32 4 0 -2147483648 ~ 2147483647
long 64 8 0L -9223372036854775808 ~ 9223372036854775807
char 16 2 'u0000' 0 ~ 65535
float 32 4 0f 1.4E-45 ~ 3.4028235E38
double 64 8 0d 4.9E-324 ~ 1.7976931348623157E308
boolean 1 faux vrai faux

Pour boolean, la documentation officielle n'est pas clairement définie, elle dépend de l'implémentation spécifique du fournisseur JVM. La compréhension logique est d'occuper 1 bit, mais en pratique, le facteur de stockage efficace de l'ordinateur sera considéré.

De plus, la taille de l'espace de stockage occupé par chacun des types de base de Java ne varie pas avec l'architecture matérielle de la machine comme la plupart des autres langages. Cette invariance de la taille de stockage est l'une des raisons pour lesquelles les programmes Java sont plus portables que les programmes écrits dans la plupart des autres langages (mentionnés dans la section 2.2 de "Java Programming Ideas").

Remarquer:

  1. Les données du longtype doivent ajouter L après la valeur , sinon elles seront analysées comme un entier.
  2. char a = 'h'char :单引号,String a = "hello" :双引号。

这八种基本类型都有对应的包装类分别为:ByteShortIntegerLongFloatDoubleCharacterBoolean

基本类型和包装类型的区别?

  • 包装类型不赋值就是 null ,而基本类型有默认值且不是 null
  • 包装类型可用于泛型,而基本类型不可以。
  • 基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道对象实例都存在于堆中。
  • 相比于对象类型, 基本数据类型占用的空间非常小。

⚠️注意 : 基本数据类型存放在栈中是一个常见的误区! 基本数据类型的成员变量如果没有被 static 修饰的话(不建议这么使用,应该要使用基本数据类型对应的包装类型),就存放在堆中。

class BasicTypeVar{
  private int x;
}
复制代码

包装类型的常量池技术了解么?

Java 基本类型的包装类的大部分都实现了常量池技术。

Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False

Integer 缓存源码:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static {
        // high value may be configured by property
        int h = 127;
    }
}
复制代码

Character 缓存源码:

public static Character valueOf(char c) {
    if (c <= 127) { // must cache
      return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    private CharacterCache(){}
    static final Character cache[] = new Character[127 + 1];
    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i);
    }

}
复制代码

Boolean 缓存源码:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}
复制代码

如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。

两种浮点数类型的包装类 Float,Double 并没有实现常量池技术。

Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出 true

Float i11 = 333f;
Float i22 = 333f;
System.out.println(i11 == i22);// 输出 false

Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false
复制代码

下面我们来看一下问题。下面的代码的输出结果是 true 还是 false 呢?

Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);
复制代码

Integer i1=40 这一行代码会发生装箱,也就是说这行代码等价于 Integer i1=Integer.valueOf(40) 。因此,i1 直接使用的是常量池中的对象。而Integer i2 = new Integer(40) 会直接创建新的对象。

因此,答案是 false 。你答对了吗?

记住:所有整型包装类对象之间值的比较,全部使用 equals 方法比较

自动装箱与拆箱了解吗?原理是什么?

什么是自动拆装箱?

  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;

举例:

Integer i = 10;  //装箱
int n = i;   //拆箱
复制代码

上面这两行代码对应的字节码为:

   L1

    LINENUMBER 8 L1

    ALOAD 0

    BIPUSH 10

    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;

    PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;

   L2

    LINENUMBER 9 L2

    ALOAD 0

    ALOAD 0

    GETFIELD AutoBoxTest.i : Ljava/lang/Integer;

    INVOKEVIRTUAL java/lang/Integer.intValue ()I

    PUTFIELD AutoBoxTest.n : I

    RETURN
复制代码

从字节码中,我们发现装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。

因此,

  • Integer i = 10 等价于 Integer i = Integer.valueOf(10)
  • int n = i 等价于 int n = i.intValue();

注意:如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。

private static long sum() {
    // 应该使用 long 而不是 Long
    Long sum = 0L;
    for (long i = 0; i <= Integer.MAX_VALUE; i++)
        sum += i;
    return sum;
}
复制代码

本文来源于我的网站 JavaGuide (Java学习+面试指南)里的Java基础知识&面试题总结(上)这篇文章。

原创不易,欢迎点赞分享,欢迎关注我在掘金的账号,我会持续分享原创干货!加油,冲

Je suppose que tu aimes

Origine juejin.im/post/7078504000005341192
conseillé
Classement