LoginSignup
0
3

More than 1 year has passed since last update.

Java Silver 3章 演算子と分岐文②

Last updated at Posted at 2021-09-07

基本データ型の型変換

基本データ型で宣言した変数は、宣言時の型で扱えるデータの範囲内であれば値を代入できる
java_basic_0401_2.png

スキャン 2021-09-07 0.59.png
上記の方向に反して型変換を行おうとするとコンパイルエラーになる

小さな物をより大きな箱に入れるのは暗黙で可能
大きな物をより小さな箱に入れるのは明示が必要(入らないと困るから)

基本データ型の暗黙型変換

変数への代入、メソッドの引数、戻り値による代入で自動で型変換が行われる
データ型ごとのデータ容量が小さい型から大きい型に順番に変換する事は可能
20210906_152247948_iOS.jpg

キャストを利用した型変換

暗黙型変換とは逆の順序で()キャストによって実行可能
20210906_152205856_iOS.jpg

キャスト演算子の実行例

public static void main(String[] args) {
  double d = 10.5;
  //int i = d; int型からDouble型は暗黙型変換は不可
  int i = (int)d;
  System.out.println("iの値:" + i);
  //foo(i);  同じ理由で不可
  foo((short)i);
 }
  static void foo(short a) {
   System.out.println("aの値:" + a);
 }
iの値:10 double型からint型になるため小数は切り捨て
aの値:10 引数としてFoo()メソッドにiがshort型で渡される

型変換の注意点

計算時の暗黙型変換

大きい物と小さい物を組み合わせる時は二つ共大きい物として扱う
(大きい方が扱いに注意が必要だから)

short s1 = 10;
s1 = ++s1;    //OK
s1 = s1 + 1;  //NG short型変数s1 と int型1 の計算では計算前に両方int型へ
              //しかし代入先はshort型変数であるためエラーとなる

ラッパークラスとBoxing/Unboxing

Integerクラスの利用:基本データ型を参照型に変換し、暗黙型変換を行わない対応がある

  public static void main(String[] args) {
    int i1 = 100;
    Integer obj = i1; // Boxing  :Integerクラスの変数に代入
    int i2 = obj;     // Unboxing:int型変数に代入
    method(i2);       // int型でメソッドの引数に渡す
  }
  static void method(Integer obj) { // Integer型で受け取る
    int i = obj + 100; // 計算も可能:参照型同士の計算では暗黙型変更は行われない
    System.out.println(i);  // ←200
  }

暗黙の型変換が行われない事によるエラー例

double d1 = 10; //OK doublega型の変数d1 へint型10を代入する際に暗黙で型変換が実行
Double d2 = 10; //NG  参照型のDouble型変数では暗黙の変換が行われず、型が異なりエラーとなる

Java変数までの感想

値や変数、計算にとにかく細かい注意が必要
データ型の設定についてはデータ領域、容量の違いによる実行速度を意識させられる
データ型の設定によりデータ領域を厳密に管理できれば、より処理の早いプログラムが組める
PHP,Javascriptではほとんど意識していなかった項目だが、Java変数の基礎に1日かかった

if else-if文

条件判定の結果によって処理を実行する
上から順に条件式が評価され、あるTrue条件が返った処理分のみ実行される

  int a = 10;
  if(a > 0){
    System.out.println("aは正の値です。");
    if(a % 2 == 0){
      System.out.println("aは偶数です。");
    }
  }else{    
    if(a == 0){
      System.out.println("aは0です。");
    }else{
      System.out.println("aは負の値です。");
    }
  }
aは正の値です。
aは偶数です。

条件式if()の{}を除いた形でTrueだと下1行までの処理が実行される
また{}を省略したまま、else後に改行するとif文が終了する

 int i = 10;
 if( i >= 5 )
  System.out.println("iは5以上です");
  System.out.println("この処理はif文に関係なく必ず実行される")

三項演算子

条件式 ? 式1 : 式2
条件式がTrueなら式1を実行し、Falseなら式2を実行する

 int num = 20;
 String str = "numの値は";
 str += num < 10 ? "10未満" : "10以上";
 //str = str + (条件式 num < 10 ? 式1"10未満" : 式2"10以上")
 //str = str + "10以上"
 //三項演算子を式の中に組み込む事も可能。シンプルに見えるが理解しにくい。

 System.out.println(str); //numの値は10以上
  }

Switch文

Switch(式)
  case 値:
    処理内容
    Break; Switch文から抜ける
  case 値:
    処理内容
  default :  最後までSwitch文から抜けなかった時の処理

public static void main(String[] args) {
  int num = 2;
  switch(num){
    case 1:    // numの値が1の場合の処理
      System.out.println("numの値は1です。");  
      break;   // breakによりswitchから抜ける
    case 2:    // numの値が2の場合の処理
      System.out.println("numの値は2です。");  
      // break文がないため、次のdefaultの処理文も実行
    default:   // numの値が1以外の場合の以下が実行される
      System.out.println("defaultです。");  
  }
}
numの値は2です。
defaultです。

caseに合致後の挙動について

public static void main(String[] args) {
 int num = 3;
  switch(num){
   case 1:
   case 2:
     // num値が1か2の場合、実行される
     System.out.println("1 または 2 ");  
     break;
   case 3:
   case 4:
     // num値が3か4の場合、実行される
     System.out.println("3 または 4 ");  
     break;
   default:  
     // num値が1から4以外の場合、実行される
     System.out.println("default");
 }
}

3 または 4

caseに合致しない場合、その処理は行われず次のcaseの判定に進むが
それは最初にcase条件の合致が発生するまでの話で
case合致から合致したcaseの処理が終わると、あとは上から順番に各caseの処理を実行する

試しに全てのbreakをコメントアウトし、変数numを2に代えると、default処理まで実行される

public static void main(String[] args) {
 int num = 1;
 switch(num){
   case 1:
   case 2:
     // num値が1か2の場合、実行される
     System.out.println("1 または 2 ");  
     // break;
   case 3:
   case 4:
     // num値が3か4の場合、実行される
     System.out.println("3 または 4 ");  
     // break;
   default:  
     // num値が1から4以外の場合、実行される
     System.out.println("default");
 }
}
1 または 2 
3 または 4
default

caseに指定する値の注意点

・caseで変数の指定はできない
・caseで定数(finalを付加した変数)の指定はできる
・finalを付加した配列では、変数の参照先の配列は固定されるが配列要素の変更は可能なため指定できない
・浮動小数点数、真偽値、Long型データの指定も不可

public static void main(String[] args) {
 int num = 0;
 int a = 10;
 final int b = 20;
 switch(num){
   case a:   // コンパイルエラー
     System.out.println("case a :の実行"); 
   case b:
     System.out.println("case b :の実行"); 
   case 30:
     System.out.println("case c :の実行"); 
 }

 String s1 = "A";
 final String s2 = "B";
 final String[] s3 = {"C"};
 switch("X"){
   case s1:  // コンパイルエラー
     System.out.println("case s1   :の実行"); 
   case s2:
     System.out.println("case s2   :の実行"); 
   case s3[0]:  // コンパイルエラー
     System.out.println("case s3[0]:の実行"); 
 }
}

3章の感想

変数の扱いはプログラムを書く上では必須の知識と思われるが、その部分のルールがとにかく厳密に決められていて、きちんと理解しないと演算、判定式、分岐文、ループ処理など基礎的な挙動を実装することも難しい。
まだクラスやオブジェクトに触れていないが、すでにJavaが難しいと言われる理由がなんとなくわかった。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3