当在Java中的字符(Char)何时表现得像字符(Char)和整数(integer)?

huangapple go评论70阅读模式
英文:

When does a Char behave like a Char and an integer in Java?

问题

我对字符作为整数和作为字符串中的字符,或者单独使用时的行为感到困惑。

char j = 'a';

for 循环
{
      String arr[i] = Character.toString(j);

		j++;

}
print arr[i];

这会打印出 abcde

为什么在这段代码中允许 j++,但当我尝试打印 j+1 时,会出现从 int 到 string 的损失转换错误?

char a = 65, b = 97;
String str = a+b+"hi";
print(str);

这会打印出 162 hi;

为什么这没有打印出 ascii(162) hi ?

英文:

I'm confused how a character behaves when it is printed as an integer and a character in a string or alone?

char j = 'a';
    
    for loop
    {
          String arr[i] = Character.toString(j);

			j++;

    }
print arr[i];

This prints abcde

Why in this code is j++ allowed , when i tried to print j+1 it gives an error of lossy conversion from int to string?

char a = 65, b = 97;
String str = a+b+"hi";
print(str);

this prints 162 hi;

Why didnt this print ascii(162) hi ?

答案1

得分: 1

char是一个误导性的名词,实际上在Java中,char作为数据类型表示一个无符号的16位整数值。也就是说,它从0开始,最大可以达到65535,如果你将其加1,它会回到0。

Java本身主要支持intlong - 虽然也有byteshortchar,但一旦可能,它们会被转换为整数。

记住以下两点:

  1. charbyteshort这些类型相对较弱,容易丢失信息,因为对这些类型进行的几乎所有数学运算都会被转换为int
  2. char是一种数值类型,与字符无关。

有一个例外:虽然char是一种数值类型,与字符无关,但我们都知道'char'实际上应该表示字符。因此,JVM中的方法将相应地进行操作。

因此,调用System.out.println((char) 65);,它会调用char版本的println,输出A,因为printlnchar版本的实现会将传递给它的整数值,查找在低位Unicode表中提供的数字,并打印找到的字符。char(数据类型)本身没有内在的特性,这纯粹是Java源代码的一个方面。

因此:

char a = 5;
a++;

是合法的,因为char是一种数值类型。

String str = a + b + "hi";输出165hi,因为Java从左到右计算+运算符,所以这相当于:

String str = (a + b) + "hi";

因此,我们来看一个例子:

char a = 65, b = 97;
System.out.println(a + b);

这将输出162 - 正如我所说,char往往会尽快转换为int,在这里发生了这种情况:a+b是一个int表达式,因此调用了int版本的println

a + b + "hi"中,相同的规则适用:(a + b)是一个值为162的int表达式,所以变成了162 + "hi",这是字符串连接,生成了字符串"162hi"

基本上,什么情况下char在Java中的行为类似于整数?它在Java中始终表现得像一个整数,除非将char表达式传递给方法,这往往会调用将传入的数字视为要在Unicode表中查找的内容的方法版本。

英文:

char is a misnomer, really. char as a datatype in java represents an unsigned 16-bit integer value. As in, it starts at 0, it goes as high as 65535, and if you then add 1 to it, it would loop back to 0 again.

Java itself mostly only supports int and long - you do have byte, short and char but these want to upconvert to an integer as soon as they can.

Keep these two things in mind:

  1. char, like byte and short are inferior and tend to get lost, as almost any mathematical operation done to char/byte/short tends to upconvert to int
  2. char is a numeric type. It has nothing to do with character.

There is one exception to the rule: While char is a numeric type and has nothing to do with characters, we all know that 'char' is supposed to represent characters. Therefore, METHODS in the JVM will act accordingly.

Thus, Calling System.out.println((char) 65);, which invokes the char variant of println, prints A, because the implementation of the char variant of println will take the integral value passed into it, and looks up the number provided in the lower-plane unicode table and prints the character it finds there. There is nothing intrinsic about char (the data type), that is purely an aspect of the source code of java.lang.System.

Thus:

char a = 5; a++;

is legal, because char is a numeric type.

String str = a + b + "hi"; prints 165hi because java evaluates the + operator left-toright, so that is shorthand for:

String str = (a + b) + "hi";

thus we get to, what is:

char a = 65, b = 97;
System.out.println(a + b);

This prints 162 - as I said, chars tend to upconvert ASAP to ints, and that happens here: a+b is an int expression, thus the int variant of println is invoked.

In a + b + "hi" the same rule applies: (a + b) is an int expression with value 162, so that boils down to 162 + "hi", which is string concatenation and makes the string "162hi".

Basically, when does char behave like an integer in java? It always behaves like an integer in java. Except if you pass char expressions to methods, that tends to invoke the version of a method that treats the incoming number as a thing to look up in a unicode table.

答案2

得分: 1

简短的答案是,在Java中,“++”运算符不会扩展。结果的数据类型与操作数的数据类型相同,在这种情况下是char。

但是,“+”运算符可能会扩展,即产生一个具有更大范围的类型的结果。将任何内容添加到char(甚至是另一个char)会将结果扩展为整数,因为编译器知道结果可能会溢出。一旦扩展,结果就不能分配给char - 它可能太大了。

当然,char上的++运算符也可能溢出。然而,Java平台规范(基本上)表示++是非扩展的。

英文:

The short answer is that that "++" operator in Java does not widen. The data type of the result is the same as the data type of the operand, which is a char in this case.

But the "+" operator may widen, that is, produce a result that is of a type with a greater range. Adding anything to a char (even another char) widens the result to integer, because the compiler knows that the result may overflow. Having widened, the result can't be assigned to a char -- it is potentially too large.

Of course, the ++ operator on a char may overflow as well. Still, the Java platform spec says (essentially) that ++ is non-widening.

答案3

得分: 0

当用`+`来连接*字符串*时,它对于*字符*不起作用。因此,当你执行`a + b`,其中`a`和`b`是字符时,Java会将这些字符转换为整数并执行整数加法。然后将`hi`附加到获得的整数结果上。

如果你想要的话,可以先加一个空字符串,告诉Java你想要的是连接,而不是加法:

    char a = 65;
    char b = 97;
    String str = "" + a + b + "hi";
    System.out.println(str);

这将打印:

> Aahi

有许多其他方法可以获得相同的输出。我最喜欢的之一是`format()`:

    System.out.format("%c%chi%n", a, b);

格式字符串中的`%c`告诉Java打印一个字符。无论传递的参数是字符还是整数,它都会打印字符。这反过来意味着以下内容有效:

    System.out.format("%chi%n", a + b);

> ¢hi

在这里,`a + b`的结果是一个`int`,但`%c`使其被转换回一个`char`,在这种情况下是`¢`。

## j++

`j++`的情况,在其中`j`是一个字符,是特殊且令人困惑的。它基本上执行与`j + 1`相同的计算,但将结果*转换回字符*(编译器优化可能导致它不是以这种方式实现的,但结果保证是这样的)。因此,你可以说你得到了与`j = (char) (j + 1);`相同的结果。

## 一般情况

你不能在字符上进行数学运算。无论何时将算术操作应用于字符,Java首先会将其转换为整数。这在很大程度上是平稳的,因为`int`可以容纳`char`的所有可能值。相反的转换并不成立。因此,Java通常不会自行从`int`转换为`char` —— 你需要明确告诉它这样做,并因此在数据丢失的情况下也要承担正确转换的责任。`++`的情况是一个例外,其中隐式地将转换回`char`。
英文:

While + works for concatenation of strings, it does not for chars. So when you do a + b where a and b are chars, Java converts those chars to integers and performs integer addition. And next appends hi to the obtained integer result.

If you want, you may put an empty string first to tell Java that you want concatenation, not addition:

	char a = 65;
	char b = 97;
	String str = "" + a + b + "hi";
	System.out.println(str);

This prints:

> Aahi

There are many other ways to obtain the same output. One of my favourites is format():

	System.out.format("%c%chi%n", a, b);

%c in the format string tells Java to print a char. It will do so no matter if the argument passed is a char or an integer. This in turn means that the following works:

	System.out.format("%chi%n", a + b);

> ¢hi

Here the result of a + b is an int, but %c causes it to be converted back to a char, in this case ¢.

j++

The case of j++ where j is a char is special and confusing. It basically performs the same calculation as j + 1 but converts the result back to char (compiler optimization may cause it not to be implemented in this way, but the result is guaranteed to be as though it were). So you may say you get the same result as from j = (char) (j + 1);.

General

You cannot do math on chars. Whenever you apply an arithmetic operation to a char, Java first converts it to an integer. This goes smoothly because an int can hold all the possible values of a char. The same is not true for the opposite conversion. Therefore Java generally refuses to convert from int to char on its own — you need to tell it explicitly to do that, and thereby you assume the responsibility of a correct conversion also in cases where data is lost. The ++ case being the exception where conversion back to char is implicit.

huangapple
  • 本文由 发表于 2020年9月3日 11:27:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63716349.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定