Javaでは、2つの文字を追加した結果はintまたはcharですか?


81

追加する際'a' + 'b'には、195を生成し、出力データ型ですcharint


3
タイプがあった場合はchar、その後の値は'a' + 'b'ないだろう195けど'Ã'
Joren

1
ここでは195です-ideone.comですが、Eclipseではありません。
オレンジ

2
あなたはアルゴリズムの本からそれを読んだ笑!私はこの演習のためにここに来ました;)
Jack Twain

回答:


133

Javaのchar、short、またはbytesを追加した結果は、intです。

2進数の昇格に関するJava言語仕様

  • オペランドのいずれかが参照型の場合、ボックス化解除変換(§5.1.8)が実行されます。次に:
  • いずれかのオペランドがdouble型の場合、もう一方はdoubleに変換されます。
  • それ以外の場合、いずれかのオペランドがfloat型の場合、もう一方はfloatに変換されます。
  • それ以外の場合、いずれかのオペランドがlong型の場合、もう一方はlongに変換されます。
  • それ以外の場合は、両方のオペランドがint型に変換されます。

ただし、複合代入演算子(+ =など)についての説明に注意してください

二項演算の結果は左側の変数の型に変換されます...そして変換の結果は変数に格納されます。

例えば:

char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK

一般に、結果のタイプを見つける1つの方法は、結果をオブジェクトにキャストして、それがどのクラスであるかを尋ねることです。

System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer

パフォーマンスに関心がある場合は、Javaバイトコードには、より小さなデータ型を使用した算術演算専用の命令さえないことに注意してください。たとえば、加算するための命令iadd(intの場合)、ladd(longの場合)、(faddfloatの場合)、dadd(doubleの場合)があり、それだけです。x += y小さい型でシミュレートするために、コンパイラーは( "int to char")のiaddような命令を使用して、intの上位バイトを使用してゼロにしますi2c。ネイティブCPUに1バイトまたは2バイトのデータ専用の命令がある場合、実行時にそれを最適化するのはJava仮想マシン次第です。

文字を数値型として解釈するのではなく、文字列として連結したい場合は、それを行う方法がたくさんあります。最も簡単なのは、空の文字列を式に追加することです。文字と文字列を追加すると文字列になるためです。これらの式はすべて、文字列になり"ab"ます。

  • 'a' + "" + 'b'
  • "" + 'a' + 'b'(これ"" + 'a'は最初に評価されるため機能します。""代わりに最後にある場合は、次のようになります"195"
  • new String(new char[] { 'a', 'b' })
  • new StringBuilder().append('a').append('b').toString()
  • String.format("%c%c", 'a', 'b')


7

について、次の式を学習することをお勧めしますchar

char c='A';
int i=c+1;

System.out.println("i = "+i);

これはJavaで完全に有効で66あり、の文字(Unicode)の対応する値を返しますc+1


String temp="";
temp+=c;
System.out.println("temp = "+temp);

これはJavaでは有効すぎて、String型変数はtemp自動的にcchar型を受け入れtemp=A、コンソールで生成します。


以下のすべてのステートメントはJavaでも有効です。

Integer intType=new Integer(c);
System.out.println("intType = "+intType);

Double  doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);

Float floatType=new Float(c);
System.out.println("floatType = "+floatType);

BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);

Long longType=new Long(c);
System.out.println("longType = "+longType);

はのcタイプですcharが、それぞれのコンストラクターでエラーなしで指定でき、上記のすべてのステートメントは有効なステートメントとして扱われます。それぞれ次の出力を生成します。

intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65

charは原始的な数値整数型であるため、変換や昇進を含むこれらの獣のすべての規則に従います。あなたはこれについて読みたいと思うでしょう、そしてJLSはこれのための最高の情報源の1つです:コンバージョンとプロモーション。特に、「5.1.2拡大プリミティブ変換」の短い部分を読んでください。


3

Javaコンパイラはそれをどちらかとして解釈できます。

プログラムを作成し、コンパイラエラーを探して確認します。

public static void main(String[] args) {
    int result1 = 'a' + 'b';
    char result2 = 'a' + 'b';
}

それがcharの場合、最初の行はエラーを表示し、2番目の行はエラーを表示しません。それがintの場合、逆のことが起こります。

私はそれをコンパイルしました、そして私は得ました.....エラーはありません。したがって、Javaは両方を受け入れます。

しかし、私がそれらを印刷したとき、私は得ました:

int:195

char:Ã

あなたがするとき何が起こるかということです:

char result2 = 'a' + 'b'

暗黙的な変換が実行されます(intからcharへの「プリミティブナローイング変換」)。


2番目のケースでは、ナローイングによる精度の低下の可能性についてコンパイラの警告が表示されなかったことに驚いています。
ホットリック2011

@eboix:あなたが書いた「コンパイラが自動的にどちらかcharまたはintにキャスト」 [原文] ...ので、正しいされていないintはに「キャスト」されていないint型と行くからint型のcharが呼び出されません「キャスト」ですが、「プリミティブ変換を狭める」; )
TacticalCoder

ええ。私もそれを期待していました。プログラムを作る前に、実際にその答えの一部を書いていましたが、警告やエラーがないことがわかったら、それを削除しました。
eboix 2011

@eboix:eh eh :)私はそれを編集したでしょうが、私はまだ2000の評判ポイントを持っていないので、編集の代わりに私のコメント; )
TacticalCoder

必要に応じて、@ user988052、元の状態に戻すことができ、ポイントを取得して編集することができます。レピュテーションポイントが2000未満の場合でも、編集できます。唯一のことは、投稿をした人が編集を受け入れる必要があるということです。あなたが正当にあなたのものである2つのポイントを得ることができるように、私は今それを元に戻します。
eboix 2011

1

バイナリ昇格規則によれば、オペランドのいずれもdouble、float、またはlongのいずれでもない場合、両方がintに昇格されます。ただし、char型を数値として扱うことは強くお勧めします。そのような場合、その目的は無効になります。


1
char数値として使用することは完全にその目的の範囲内であるため、JLSはそのような使用に非常に多くの言い回しを捧げます。
ルー・ブロック2017年

1

すでに正解がありますが(JLSで参照)、int2つcharのを追加したときにが得られることを確認するためのコードを次に示します。

public class CharAdditionTest
{
    public static void main(String args[])
    {
        char a = 'a';
        char b = 'b';

        Object obj = a + b;
        System.out.println(obj.getClass().getName());
    }
}

出力は

java.lang.Integer


ボクシングのコンバージョンをミックスに投入したため、これは説得力のある検証ではありません。タイプintIntegerは同じものではありません。より説得力のある検証はa + bint変数または変数に割り当てようとすることcharです。後者は、「あなたが割り当てることができない効果で述べているコンパイルエラー与えintchar」を。
スティーブン

0

charUnicode値として表され、Unicode値は\uその後にHexadecimal値が続きます。

charプロモートされた値に対する算術演算と同様にint、の結果'a' + 'b'は次のように計算されます。

1.)Unicode対応するchar使用に値を適用しますUnicode Table

2.)16進数から10進数への変換を適用して からDecimal値に対して操作を実行します。

    char        Unicode      Decimal
     a           0061          97
     b           0062          98  +
                              195

Unicode To Decimal Converter

0061

(0 * 16 3)+(0 * 16 2)+(6 * 16 1)+(1 * 16 0

(0 * 4096)+(0 * 256)+(6 * 16)+(1 * 1)

0 + 0 + 96 + 1 = 97

0062

(0 * 16 3)+(0 * 16 2)+(6 * 16 1)+(2 * 16 0

(0 * 4096)+(0 * 256)+(6 * 16)+(2 * 1)

0 + 0 + 96 + 2 = 98

したがって、 97 + 98 = 195


例2

char        Unicode      Decimal
 Ջ           054b         1355
 À           00c0          192 
                      --------
                          1547    +
                          1163    -
                             7    /
                        260160    *
                            11    %

これは質問が求めているものではありません。
スティーブン

参考までに、上記のコメントに対する私の詳細な回答は、削除された投稿からの私の回答の移行の背後にある理由を説明するmodによって削除されました。SOモデレーションの欠陥を隠すために私の応答が削除された場合、少なくとも上記のコメントを削除するか、別のコメントを書く必要がないように何らかの方法で聴衆に示すことができますか?SO改造への質問
Pavneet_Singh

私は私のコメントを支持します。私があなたに返信したように...しかしその後削除しました...あなたがこの質問をここに投稿した理由は、それが質問に対して95%オフトピックであり、以前の回答の5%の繰り返しであるという事実を変えません。無駄な労力の結果を保存したい場合は、ハードドライブに保存する方が適切です。または、関連する他の質問を見つけてください。
スティーブン

モデレーターに不満がある場合は、meta.stackoverflow.comで取り上げてください。そして証拠を提供します。ここでやろうとしているのは、整理整頓>> this << Q&Aです。
スティーブン

私はあなたの見解を理解していますが、一部の読者を助けるかもしれない追加の値として、例でUnicode変換の詳細を無視するという事実を理解することはできませんので、この答えを保持したいと思います(トピック)。パワーやサポートなしでそのようなことをするのは簡単ではなく、多くの時間と労力を要するので、私はメタや同様の場所を避けます。私は心の平安を保つことを好みます。
Pavneet_Singh

0

一方でBoannの答えが正しいか、の場合に適用される合併症がある定数式、彼らがに表示されたときに割り当てコンテキスト

次の例を検討してください。

  char x = 'a' + 'b';   // OK

  char y = 'a';
  char z = y + 'b';     // Compilation error

何が起こっている?彼らは同じことを意味しますね?そして、なぜそれが割り当てることが合法であるintとのchar最初の例では?

定数式が割り当てコンテキストに現れると、Javaコンパイラは式の値を計算し、それが割り当て先の型の範囲内にあるかどうかを確認します。そうである場合、暗黙のナローイングプリミティブ変換が適用されます。

  • 最初の例で'a' + 'b'は、は定数式であり、その値はに収まるcharため、コンパイラはint式の結果をchar。に暗黙的に絞り込むことができます。

  • 2番目の例でyは、は変数であるためy + 'b'、定数式ではありません。したがって、Blind Freddyは値が適合することを確認できますが、コンパイラーは暗黙的なナローイングを許可せintず、にを割り当てることができないというコンパイルエラーが発生しますchar

このコンテキストで暗黙的なローイングプリミティブ変換が許可される場合には、他にもいくつかの注意点があります。詳細については、JLS5.2およびJLS15.28を参照してください。

後者は、定数式の要件を詳細に説明しています。それはあなたが思うかもしれないものではないかもしれません。(たとえば、yとして宣言するだけでfinalは役に立ちません。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.