71005


キャストされているはずなのに、resultにエラーが出てしまうのはどうしてでしょうか？

[code]

    public String net(String in) {
        char[] result = in.toCharArray();
    
        for(int i = 0; i < result.length; i++) {
            if(result[i] == 0) {
                result[i] = 9;
            }else {
                --result[i];
            }
        }
    
        //String result01 = String.copyValueOf(result);//char[]暗黙変換してくれるから不必要。無駄な処理
    
        return result;　//エラーが出る
    }
    
[/code]

int型でもエラーが出てしまいます。

[code]

    public String net(String in) {
        char[] result = in.toCharArray();
    
        for(int i = 0; i < result.length; i++) {
            if(result[i] == 0) {
                result[i] = 9;
            }else {
                --result[i];
            }
        }
        //String result01 = String.copyValueOf(result);
        int no01 = result;
        return no01;
    }
    
[/code]

以下のコードを実行したらたしかに自動でキャストされておりましたので、上記でもできると考えました。

[code]

    public class TypeCast {
    
        public static void main(String[] args) {
            char ch = '1';
    
            // 暗黙的にint型、double型にキャストする。
            int i = ch;
            double d = ch;
    
            System.out.println(ch + "をint型にキャストした結果: " + i);
    
            System.out.println(ch + "をdouble型にキャストした結果: " + d);
    
            // 引数がdouble型のメソッドに対して、char型を引数として渡す。
            foo(ch);
        }
    
        static void foo(double d) {
            System.out.println("double型: " + d);
        }
    
    }
    
[/code]


CC BY-SA 4.0
2020-10-07T07:03:37.317
70986
2020-10-08T01:29:07.010
2020-10-07T08:02:09.420
3060
32774
question
java
型変換ができていない？


[他のご質問](https://ja.stackoverflow.com/q/70994)の回答の方が詳しいので、踏み込んだ内容はそちらを熟読していただくことをお勧めしつつ、簡単な解説をします。

ご質問の通り`return result;`では、下記のエラーが発生します。  
エラー: 不適合な型: char[]をStringに変換できません:

これが発生する理由は、Javaは **何でも暗黙的な型キャストすることはできない** からです。  
コメントにあるQiitaの記事や冒頭の回答にある通り、`文字コード = 数字`です。

パソコンのメモリやディスクでは0と1しか扱えませんので、"ABC"を文字としてメモリに配置することはできません。  
なので、メモリ上で文字を扱うためには全ての数字、アルファベット、かな漢字を0と1で表すようにアメリカの研究者たちが決めました。  
「asciiって文字コードを作るぞ！'0'って文字はasciiコード上では48な。48は16進数だと0x30だし2進数だと0b00110000だ」という取り決めがありました。  
(なぜ'0'って文字がコード上で0になっていないのかは、歴史的経緯やパソコンの制約に由来するのですが割愛します)  
パソコンもJavaも上記の文字コードの約束を守っています。

ちなみに、char型の'0'(int型で48)からint型の1をひくとchar型の'/'(int型で47)になります。  
それはそうですよね。48-1=47です。  
47は16進数に直せば0x2Fですし、2進数に直せば0b00101111になります。  
なぜ'/'がint型で47なのかというと、asciiコードを決めた人がそう決めたからです。

さて、1文字を表すchar型ならば文字コードを暗黙的に数字に変換することができます。  
つまり下記のようにchar型に数値を入れたりint型に文字コードを入れたりすることができます。  
この挙動を理解すると[回答](https://ja.stackoverflow.com/a/70995)のコメントにある「実行したら９が表示された」理由が分かってきます。

[code]

    char c = 48;
    System.out.println(c); //char型だから'0'と表示する
    int i = '0';
    System.out.println(i); //int型だから48と表示する
    
[/code]

次に`char`と`char[]`と`String`は全くの別物です。  
どのくらい違うかというと、砂粒とレンガと建物くらい違います。  
砂粒を集めて固めるとレンガになるように、複数のcharを集めた **配列** がchar[]です。  
char[]をどのようなルールでintにするのかは決まっていません。  
例えば下記のコードを考えます。

[code]

    char[] c = {'1', '2', '3'};
    int i = c;
    
[/code]

この時、iは文字コードの49+50+51になるでしょうか、123になるでしょうか、1+2+3で6になるでしょうか。  
Javaが暗黙的な変換ルールを定めていないので、この処理はエラーになります。

同様にchar[]とStringも別物です。  
String型はcharを集めて文字列にしたものですが、文字列を扱うための便利な機能が用意されています。

ご質問のコードではresultはchar[]型で、netメソッドの戻り値はString型です。  
char[]型をString型に変換する時、様々な変換方法があります。

`char[] c = {'1', '2', '3', 'あ', 'い', 'う'};`とした場合に、  
`123あいう`という単純に連結した文字列が欲しい人もいますし、  
`123%E3%81%82%E3%81%84%E3%81%86`というURLエンコードした文字列が欲しい人も、  
`&#x31;&#x32;&#x33;&#x3042;&#x3044;&#x3046;`という文字コードの羅列が欲しい人もいます。

「`123あいう`が欲しいだろ。常識で考えて」と思うかもしれませんが、コンピュータの世界ではそう簡単に行きません。  
この背景を踏まえてJavaが暗黙的な変換ルールを定めていないので、この処理もエラーになります。  
そして暗黙的ではなく明示的に単純に連結した文字列を出力する機能として`String#copyValueOf`が用意されているのです。  
これはString型の便利な機能のひとつです。

まとめです。

  * 自動キャストには限界がある
  * String型とchar[]配列とchar型は全然別物
  * char型とint型は自動キャストできるけれど、String型とchar[]、char[]とintは自動キャストできない
  * 文字コードは数字と約束で成り立っている
  * [他のご質問](https://ja.stackoverflow.com/q/70994)の回答の方が詳しいので、踏み込んだ内容はそちらを熟読してください


CC BY-SA 4.0
2020-10-08T01:29:07.010
71005
2020-10-08T01:29:07.010
9820
70986
answer