Java Primitive Conversions – Java原形转换

最后修改: 2017年 3月 7日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

Java is a typed language which means it utilizes the concept of types. There are two distinct type groups:

Java是一种类型化的语言,这意味着它利用了类型的概念。有两个不同的类型组。

  1. primitive data types
  2. abstract data types.

In this article, we will focus on conversions of primitive types.

在这篇文章中,我们将重点讨论原始类型的转换。

2. Overview of Primitives

2.基元概述

The first thing we have to know is what kind of values may be used with primitive types. There are eight primitive types which are:

我们必须知道的第一件事是什么类型的值可以与原始类型一起使用。有八个原始类型,它们是

  • byte – 8 bits and signed

    byte – 8位,有符号的

  • short – 16 bits and signed

    short – 16位,有符号的

  • char – 16 bits and unsigned, so that it may represent Unicode characters

    char – 16位,无符号,因此它可以代表Unicode字符。

  • int – 32 bits and signed

    int – 32位,有符号。

  • long – 64 bits and signed

    long – 64位且有签名的

  • float – 32 bits and signed

    float – 32位,有符号。

  • double – 64 bits and signed

    double – 64位,有符号。

  • boolean – it’s not numeric, may only have true or false values

    boolean – 它不是数字,可能只有truefalse值。

This is not intended to be an extensive discussion about primitives and we will talk a little more about their details as needed during the conversions.

这并不是要对基元进行广泛的讨论,我们会在转换过程中根据需要多谈一些关于基元的细节。

3. Widening Primitive Conversions

3.拓宽原始转化率

When we need to convert from a primitive that is simpler or smaller than the destination type, we don’t have to use any special notation for that:

当我们需要从一个比目标类型更简单或更小的基元进行转换时,我们不必为此使用任何特殊的符号。

int myInt = 127;
long myLong = myInt;

During widening conversion, the smaller primitive value is placed over a larger container, which means that all the extra space, on the left of the value, is filled with zeros. This may also be used to go from the integer group to the floating point:

在加宽转换过程中,较小的原始值被放在较大的容器上,这意味着所有额外的空间,在值的左边,都被零填满。这也可用于从整数组到浮点组的转换。

float myFloat = myLong;
double myDouble = myLong;

This is possible because the moving to a wider primitive does not lose any information.

这是可能的,因为移动到一个更宽的基元不会损失任何信息。

4. Narrowing Primitive Conversion

4.狭义的原始转换

Sometimes we need to fit a value that is larger than the type used in the variable declaration. This may result in information loss since some bytes will have to be discarded.

有时我们需要适应一个比变量声明中使用的类型更大的值。这可能会导致信息损失,因为一些字节将不得不被丢弃。

In this case, we have to explicitly express that we are aware of the situation and we agree with that, by using a cast:

在这种情况下,我们必须明确表达我们知道这种情况,并且我们同意这种情况,通过使用投名状。

int myInt = (int) myDouble;
byte myByte = (byte) myInt;

5. Widening and Narrowing Primitive Conversion

5.拓宽和缩小原始转换

This situation happens in a very specific case when we want to convert from a byte to a char. The first conversion is the widening of the byte to int and then from the int it is narrowed down to char.

这种情况发生在非常特殊的情况下,当我们想从byte转换到char。第一次转换是将byte扩大到int,然后从int缩小到char

An example will clarify this point:

一个例子可以说明这一点。

byte myLargeValueByte = (byte) 130;   //0b10000010 -126

The binary representation of 130 is the same for -126, the difference is the interpretation of the signal bit. Let’s now convert from byte to char:

130的二进制表示与-126是一样的,区别在于对信号位的解释。现在让我们从byte转换到char

char myLargeValueChar = (char) myLargeValueByte;
  //0b11111111 10000010 unsigned value
int myLargeValueInt = myLargeValueChar; //0b11111111 10000010 65410

The char representation is a Unicode value, but converting to an int showed us a very large value which has the lower 8 bits exactly the same as -126.

char表示的是一个Unicode值,但转换为int后,我们看到了一个非常大的值,它的低8位与-126完全相同。

If we convert it again to byte we get:

如果我们再次将其转换为byte,我们得到。

byte myOtherByte = (byte) myLargeValueInt; //0b10000010 -126

The original value that we used. If the whole code was starting with a char the values will be different:

我们使用的原始值。如果整个代码是以char开始的,数值就会不同。

char myLargeValueChar2 = 130; //This is an int not a byte! 
  //0b 00000000 10000010 unsigned value
        
int myLargeValueInt2 = myLargeValueChar2; //0b00000000 10000010  130
        
byte myOtherByte2 = (byte) myLargeValueInt2; //0b10000010 -126

Although the byte representation is the same, which is -126, the char representation gives us two different characters.

尽管byte表示法是相同的,也就是-126,但char表示法给了我们两个不同的字符。

6. Boxing/Unboxing Conversion

6.装箱/拆箱的转换

In Java, we have a Wrapper Class for each primitive type, this is a clever way of providing programmers with useful processing methods, without the overhead of having everything as a heavyweight object reference. Since Java 1.5 the ability to automatically convert to/from a primitive to an object and back was included and its achieved by simple attribution:

在Java中,我们为每个原始类型都有一个封装类,这是一种为程序员提供有用的处理方法的聪明方法,而不需要把所有东西都作为一个重量级的对象引用。自Java 1.5以来,自动转换到/从基元到对象并返回的能力被包括在内,其通过简单的归属实现。

Integer myIntegerReference = myInt;
int myOtherInt = myIntegerReference;

7. String Conversions

7.字符串转换

All the primitive types may be converted to String through their Wrapper Classes, which override the toString() method:

所有的原始类型都可以通过它们的封装类被转换为String,封装类重写了toString()方法。

String myString = myIntegerReference.toString();

If we need to go back to a primitive type, we need to use a parse method defined by the corresponding Wrapper Class:

如果我们需要回到一个原始类型,我们需要使用相应的封装类所定义的解析方法。

byte  myNewByte   = Byte.parseByte(myString);
short myNewShort  = Short.parseShort(myString);
int   myNewInt    = Integer.parseInt(myString);
long  myNewLong   = Long.parseLong(myString);

float  myNewFloat  = Float.parseFloat(myString);
double myNewDouble = Double.parseDouble(myString);
boolean myNewBoolean = Boolean.parseBoolean(myString);

The only exception here is the Character Class because a String is made of chars anyway, this way, considering that probably the String is made of a single char, we can use the charAt() method of the String class:

这里唯一的例外是字符类,因为字符串无论如何都是由字符组成的,这样一来,考虑到字符串可能是由一个字符组成的,我们可以使用字符串类的charAt()方法。

char myNewChar = myString.charAt(0);

8. Numeric Promotions

8.数字促销

To execute a binary operation, it is necessary that both operands are compatible in terms of size.

要执行二进制操作,必须使两个操作数在大小上兼容。

There is a set of simple rules that apply:

有一套简单的规则适用。

  1. If one of the operands is a double, the other is promoted to double
  2. Otherwise, if one of the operands is a float, the other is promoted to float
  3. Otherwise, if one of the operands is a long, the other is promoted to long
  4. Otherwise, both are considered int

Let’s see an example:

让我们看一个例子。

byte op1 = 4;
byte op2 = 5;
byte myResultingByte = (byte) (op1 + op2);

Both operands were promoted to int and the result must be downcast to byte again.

两个操作数都被提升为int,结果必须再次下移为byte

9. Conclusion

9.结论

Conversion between types is a very common task on daily programming activities. There is a set of rules that govern the ways in which statically typed languages operate those conversions. Knowing this rules may save a lot of time when trying to figure out why a certain code is compiling or not.

类型之间的转换是日常编程活动中一项非常常见的任务。有一组规则制约着静态类型语言操作这些转换的方式。当试图弄清楚为什么某段代码可以编译或不能编译时,了解这些规则可能会节省很多时间。

The code used in this article can be found over on GitHub.

本文中使用的代码可以在GitHub上找到over