はじめに
普段はiOSエンジニアとしてSwiftを使用してアプリ開発をしています。
サーバーはJavaメインで書かれているので勉強がてらSwiftとJavaの互換表を作ってみます。
基礎的なところから少しづつ更新していきたいと思っています。
ただSwift歴も浅いのでJavaは勿論、Swiftも間違いや、より良い書き方、こんな書き方もあるよ! といった際はコメントでご教示いただけますと幸いです。
変数
変数
// 宣言
var num: Int
// 代入
num = 0
// 初期化 (var 変数名 = 値)
var num = 0
var str = "もしもし"
var bool = true
// 宣言
int num;
// 代入
num = 0;
// 初期化 (データ型名 変数名 値;)
int num = 0;
String str = "もしもし";
boolean bool = true
・Javaには;セミコロンが付きます。忘れそうですね。
・Stringは大文字から始まります。理由は後述します。
定数
// let 変数名 値
let num = 0
let num: Int = 0
let greetingStr = "もしもし"
// final データ型名 変数名 値;
final int NUM = 0;
final String GREETING_STR = "もしもし";
・先頭に「final」というキーワードを付与します。
・定数名はすべて大文字のアンダースコア形式で命名します。
数値
// 整数
var int: Int = 0 // 実行環境によって32bit or 64bit
// 浮動小数点型
var float: Float = 0.1 // 10の38乗の正負 最小で6桁の精度
var double: Double = 0.1 // 10の308乗の正負 最小で15桁の精度
// 整数
byte by = 0; // 8ビット
short sh = 0; // 16ビット
int in = 0; // 32ビット
long lo = 0; // 64ビット
// 浮動小数型
float fl = 0.1; // 32ビット
double dou = 0.1; // 64ビット
// 末尾にF,LをつけることでFloat,Long型になる
num = 100F; // float型
num = 200L; // long型
・SwiftのIntが実行環境によって範囲が変わるのは知りませんでした。
文字 論理
// 文字列
var str: String = "Hello"
// Character型
var character: Character = "a"
// 論理型
var bool: Bool = true
// 文字列
String str = "Hello";
// Character型
char ch = 'あ';
// 論理型
boolean bool = true;
・Javaのcharacter型はシングルクォーテーションで囲います
配列
var stringArray: [String] = ["サウナ", "水風呂", "ロウリュー"]
var boolArray: [Bool] = []
配列名.countで要素数を取得
// データ型[] 配列名 = new データ型[要素数];
String[] stringArray = new String["サウナ", "水風呂", "ロウリュー"];
boolean[] boolArray = new boolean[3]; // 3つの要素が入る配列
boolArray[0] = true;
int[] nums; // 配列の宣言
int[] nums2 = {0, 1, 2}
配列名.length で要素数を取得
・要素数を宣言するのは不思議な感覚です
辞書
// 辞書
var intDictionary: [String: Int] = ["サウナ": 37, "水風呂": 32, "ロウリュー": 6]
// 辞書
//Map, HashMap, Hashtable, LinkedHashMap, TreeMap...
Map<String, int> map1 = new HashMap<String, int>() {
put("サウナ", 37);
put("水風呂", 32);
put("ロウリュー", 6);
};
・HashMapが辞書型に対応するようですが、、理解を深めて追って詳細について記載したいと思います。
タプル
let position: (Int, Int, Int) = (35, 2, 90)
let x = position.0
let y = position.1
let z = position.2
// Javaにタプルはありませんが、クラスやライブラリを使ってタプルとして使う方法があるようです。
Optional nil、null許容
var str: String?
var int: Int? = 0
var double: Double? = nil
var bool: Bool?
String str;
Integer int = 0;
Double double = null;
Boolean boolean;
下記がプリミティブ型です。整数値や実数値といった、具体的な「値」を格納するための変数です。nullは入りません。
byte、short、int、long、float、double、char、boolean
プリミティブ型には、それぞれのクラス版(参照型)として「ラッパークラス」が存在します。
IntegerやDoubleなどと大文字で表記します。Stringにはプリミティブ型は存在せずクラスのみとなるため大文字で記述します。
参照型はメモリに保存されたアドレスを参照値として変数に保存
クラスは3000種類以上
それとラッパークラス同士の比較は気をつけましょう。基本的にequalsメソッドを使っておけば良さそうです。
比較内容 | 結果 |
---|---|
ラッパークラスとラッパークラスを==で同値比較 | false |
ラッパークラスとラッパークラスをequalsメソッドで同値比較 | true |
ラッパークラスとプリミティブ型を==で同値比較 | true |
ラッパークラスとプリミティブ型をequalsメソッドで同値比較 | true |
キャスト
var int = 3
var double = 4.5
var result = Double(int) + double
int numInt = 3;
double numDouble = 4.5
double result = (double)numInt + numDouble;
・int型の値をlong型に代入するなどの拡大変換は可能ですが、その逆でlong型からint型に変換する縮小変換はできません。
演算子
基本的な演算子(>, <, ==, !=等)はSwiftもJavaも同じです。
少し話が変わりますがSwiftは違う型同士の計算はエラーとなります。
Javaは代入する変数が計算結果と一致していれば代入できます。
var numInt = 3
var double: Double = 1.1
var double2: Double
double2 = numInt * double // エラー
int num = 3;
double numDouble = 1.1;
double numDouble2;
numDouble2 = num * numDouble; // 実行可能
nilチェック
if let hoge = hoge {
print(hoge)
}
if hoge != nil {
print(hoge)
}
guard let hoge = hoge else {
return
}
String str = null;
if (StringUtils.isEmpty(str)) {
System.out.println("str == null");
}
// strがnull
if (str == null) {
System.out.println("str == null");
}
// strがnull以外
if (str != null) {
System.out.println("str != null");
}
・Javaはnilではなくnullです
構文
if文
if dollar > 130 {
print("円安")
} else if dollar < 90 {
print("円高")
}
if age >= 18 {
print("成人")
} else {
print("未成年")
}
if (dollar > 130) {
System.out.println("円安");
} else if dollar < 90 {
System.out.println("円高");
}
if (age >= 18) {
System.out.println("成人");
} else {
System.out.println("未成年");
}
Switch
switch num {
case 1: print("1")
case 2: print("2")
case 3: print("3")
default: print("default")
}
switch (num) {
case 1: { System.out.print("1");
break;
}
case 2: { System.out.print("2");
break;
}
case 3: { System.out.print("3");
break;
}
default: { System.out.print("default") }
}
case 節を {} で囲んでbreak;を記述します。
while
var num = 0
while num < 3 {
num += 1
}
int num = 0;
while (num < 3) {
num++;
}
・Swift3以降++は廃止されたそうです。
for文
for i in 0..<3 {
print(i)
}
// for(式1; 条件式; 式2) { 処理 }
// for(カウンタ変数の準備,カウンタ変数の条件式, 実際に実行する式)
for(int i = 0; i < 3; i++) {
System.out.print(i);
}
・Javaのfor文は一見複雑そうですが行っていることはSwiftと同じです。
・昔はSwiftもJavaのようにC言語のようなfor文を使っていたようですが廃止されたそうです。
クラス
クラス
class Swift {
}
Class Java {
// メインメソッド
public static void main(String[] args) {
}
}
・クラスはSwift同様大文字から記述します。
・メインメソッドとはプログラムを実行する時に最初に呼び出されるメソッド。メインメソッドに関しては調べてみるとC言語の流れを汲んでいるなどさらっと調べてみても面白いです。
init (Java コンストラクタ)
class Human {
var name:String
var age:Int
init(name:String, age:Int){
self.name = name
self.age = age
}
}
let miyamoto = Human(name: "宮本武蔵", age: 29)
class Human {
String name;
int age;
// 引数を持つコンストラクタ
public Human(String name, int age) {
this.name = name;
this.age = age;
}
}
//インスタンスの生成
Human miyamoto = new Human("宮本武蔵", 29);
構造体
struct Human {
var name: String
var height: Int
}
let humanA = Human(name: "サウナ太郎", height: 180)
public class Human {
private final String name;
private final int height;
public Human(String name, int height) {
this.name = name;
this.height = height;
}
}
Swiftはイニシャライザが自動生成されるので基本的なイニシャライザは記載しなくても使用できる。
Javaにはstructの概念がないためではイミュータブル(変更不可能な)なクラスとして宣言する。
プロトコル
protocol Sauna { ... }
public interface Animal { ... }
インターフェースはプロトコル同様にクラスにメソッドの記述を強制する。
インターフェースはクラスで共通する仕様を定義するとき、抽象クラスは他のクラスの処理の骨組みを定義するときに利用する。
アクセス修飾子
Swift
修飾子 | 同クラス | モジュール | ファイル | 継承、オーバーライド |
---|---|---|---|---|
open | ○ | ○ | ○ | ○ |
public | ○ | ○ | ○ | - |
fileprivate | ○ | ○ | ○ | ○ |
internal | ○ | ○ | - | - |
private | ○ | - | - | - |
※上記リスト間違いあればご指摘ください
・open そのモジュールをインポートしていればアクセス可能。継承やoverrideもできる。
・public そのモジュールをインポートしていればアクセス可能。継承やoverrideはできない。
・fileprivate 同一ファイルからアクセス可能
・internal 同一モジュールからアクセスできる。継承やoverrideもできる。特にアクセス修飾子をつけない場合はデフォルトでこのレベルの制限になる。
・private(set) setの時はprivateと同じ制限、getの時は同一モジュール内からアクセスできる
・private そのクラスまたは構造体の中でのみアクセス可能(extension内でもアクセス可能)
Java
修飾子 | 同クラス | 同パッケージ | サブクラス | 他 |
---|---|---|---|---|
public | ○ | ○ | ○ | ○ |
protected | ○ | ○ | ○ | - |
(なし) | ○ | ○ | - | - |
private | ○ | - | - | - |
関数
返り値のない関数
private func sayHello() {
print("Hello")
}
private static void sayHello() {
System.out.println("Hello");
}
・privateは修飾子です
返り値がある関数
func getAge() -> Int {
return 20
}
public static int getAge(){
return 20;
}
返り値と引数がある関数
func happyBirthDay(age: Int) -> Int {
age += 1
return age
}
public static int happyBirthDay(int age) {
age++;
return age;
}
メソッドの前にstatic修飾子を付けると、staticメソッドになります。
staticメソッドは、クラスのインスタンス化なしに直接呼び出して使用できます。staticメソッドを使用するメリットは以下の通りです。
・インスタンス化せずに利用できる
・状態に依存しないことが保証される
・インスタンスごとに動作が変わらないことが保証される
関数の呼び出し
var age = getAge()
var newAge = happyBirthDay(age: age) // getAgeで取得したageを代入(Intの20)
// newAge 21
int age = getAge;
int newAge = happyBirthDay(age); // getAgeで取得したageを代入(intの20)
// newAge 21
その他
とりあえずよく使いそうなメソッドや処理はここにまとめようと思います。
// IntからStringへ変換
var str = String(5)
// StringからInt?へ変換
var int = Int("5")
// intからStringへ変換
int num = 10;
Integer numInt = Integer.valueOf(num); // Intergerへ変換
String str = numInt.toString(); // Stringへ変換
// StringからIntへ変換
int int1 = Integaer.parseInt("5");
終わりに
ある程度まとまったのでひとまず投稿しますが、今後も追記していきます。
SwiftもJavaもまとめている中で学びがあり面白かったです。