Java
Swift
static
final

【Swift vs Java】staticとfinalをいい加減理解しよう

More than 1 year has passed since last update.


Static

staticのClassのメンバーで、変数、メソッド、ブロック、ネストクラスにつけることができる。(だいたいvariableとmethod)

staticキーワードをつけると、インスタンスなしでクラスの中にあるstaticメンバーにアクセスできる。また、インスタンスをいくら作っても全てのインスタンスで同じ値やメソッドが共有されます。

'static'なメソッドはインスタンスに属していないため、インスタンスのメンバーにアクセスできない。'static'なメンバーは'static'メソッドからしかアクセスできない。


どういう時に使うの?

クラスが作成されてようが、されてまいが関係ない時にstaticを使う。例えば、Student(学生)クラスの中に、名前と学校名の変数があったとしたら、

名前はユニークなので、instance variableで学校名はその生徒がいなくても独立しているのでstatic variableです。

メソッドも同じで、生徒と関係ないメソッドはstaticにしておく感じ。

何が便利って、クラスの中のstaticを変更すると、クラスを参照している全てのオブジェクトのstatic値が変わること!


Java


Main.java

public static void main(String args[]){

Student s1 = new Student("Yagami");
Student s2 = new Student("Dekisugi");

s1.display();
s2.display();

System.out.println(Student.collegeName);
}



Student.java

public class Student {

String name;
static String collegeName ="Tokyo University";

Student(String newStudentName){
name = newStudentName;
}
void display (){
System.out.println(name+" "+collegeName);
}
}



Swift


Main.swift

let s1 = Student("Yagami")

let s2 = Student("Dekisugi")

s1.display()
s2.display()

print(Student.collegeName)



Student.swift

public class Student {

var name:String?
static var collegeName:String?

init(_ name:String) {
self.name = name
}

func display() {
print("\(name) \(Student.collegeName)")
}
}


ポイント1

JavaのSwiftもだいたい同じですが、

唯一の違いが、static変数のアクセス方法です。


  • Swiftではクラス内にいようがいまいが、staticメンバーをアクセスするのに、

    Student.collegeNameと、クラス名を冒頭につける


  • Javaではクラス内にいるときは、冒頭にクラス名をつけなくてもよい


ポイント2

上記を見ると、設定していないのに二人の生徒の学校名が"Tokyo University"になっている。そして、staticな変数はもクラスに参照されないため、コンストラクターでも使われない!


クラス内でのstatic変数とstaticメソッドのアクセス権


Java


Prorammer.java


public class Programmer {

private static boolean isGood;
private int experienceYears;

public static void main(){

// StaticなメソッドからはStatic変数をアクセスできる
isGood = true;

//*Staticなメソッドからnon-Static変数はアクセスできない。参照を使わないとだめ
Programmer person1 = new Programmer();
person1.experienceYears = 10;
}

// non-staticなメソッドからstatic変数はアクセスできる
public void setExperienceYears(int years){
this.experienceYears = experienceYears;
}

// non-staticなメソッドからnon-static変数はアクセスできる
public void setIsGood(Boolean isGood){
isGood = isGood;
}
}



Swift

class Programmer{

static var isGood:Bool?
var experienceYears:Int?

static func execute(){
isGood = true

//static メソッドからはnon-static変数はアクセスできない。インスタンスが必要
let person1 = Programmer();
person1.experienceYears = 10;

}

//non-staticなメソッドからはアクセスできる
func setExperience(_ years:Int){
self.experienceYears = years
}

//non-staticなメソッドからはstatic変数を直接アクセスできない。クラス名が必要。
func setIsGood(_ isGood:Bool){
Programmer.isGood = isGood
}
}


Final

Finalをつけた時のそれぞれの特徴。変数の意味だけが変わる


Java

Final Class
Final Variable
Final Method

no child
constant
no override


Swift

Final Class
Final Variable
Final Method

no child
no override in subclass
no override


Final Class

Java

//これはOkだけど

final public class Final extends Queen { }

//これはNG = compileエラー
public class King extends Final { }

Swift

//OK

final class Final: Programmer { }

//NG = compileエラー
final class Student: Final { }


Final Variable

Java

Constantになるので値が変えられなくなる。Swiftでいうletですね。

Swift

//OK クラス内ではfinal変数の値を変更できる。

class Final{
final var name = "Ayako Sayama"
init() { name = "Ayako Superman" }
}

//NG Compileエラー
class Student: Final{
override var name = "new name"
}


Final Method

*Finalメソッドはそのままなのでコードはスルーします。

要するに、中身を他の子クラスなどで、書き換えられないという感じです。