Javaのfinal修飾子とは?

このQ&Aのポイント
  • Javaのfinal修飾子は、メソッドのオーバーライドや変数の値の変更、クラスの継承を制限します。
  • final修飾子を引数につけた場合、変更が可能な参照型の場合は参照先の値を変更できます。
  • 交換関数であるswap関数について、基本型の場合は値のコピーが行われ、参照型の場合はポインタの値の交換が行われます。
回答を見る
  • ベストアンサー

final修飾子

Javaでfinal修飾子があると学びました. ・メソッドはオーバーライドできない ・変数は値の変更ができない ・クラスは継承できない この3点を実現することが可能ですよね? #間違っている・他にもあるなら教えてください. 私はfinalを引数につけてみました. public class Test {   public static void main(String[] args) {      char[] s = {'s','a','t','o'};      System.out.println(s);      modify(s);      // finalのはずが変更されている      System.out.println(s);      Integer i = 3;      Integer j = 6;      swap(i, j);      System.out.println(i + ":" + j);      Foo f1, f2;      f1 = new Foo();      f2 = new Foo();      f1.i = 3;      f2.i = 6;      swap(f1, f2);      System.out.println(f1.i + ":" + f2.i);    }    static void modify(final char[] s) {      s[0] = 'k';    }    static void swap(Integer i, Integer j) {      Integer temp;      temp = i;      i = j;      j = temp;    }    static void swap(Foo f1, Foo f2) {      int temp;      temp = f1.i;      f1.i = f2.i;      f2.i = temp;    } } class Foo {    int i; } modify関数でfinal修飾子をつけるとsatoがkatoにならないと予想していました. ですが,実際にはコンパイルエラーにもならずsato→katoになりました. final修飾子はC言語でいうところのchar * const c;でしょうか? #ポインタの値は変更できないが,参照先の値は変更できるということですか? あと,swap関数についても質問があります. そもそもポインタがないので,基本型を実引数に与えるときはコピーされ, 参照型はコピーされないですよね? なので,swap関数を2つ用意してみました. Fooクラスのswap関数,Integerクラスのswap関数の2つです. Fooクラスがうまく交換でき,Integerクラスが交換できない理由がわかりません. #Integer temp;を使って参照値を交換していると思うのですが,違うのでしょうか?

  • Java
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

Cをある程度ご存知なようなので. 参照は、ポインタをイメージすると、理解の助けになるでしょう。 > inal修飾子はC言語でいうところのchar * const c;でしょうか? そうです。 > あと,swap関数についても質問があります あなたのコードと同等のCのコードは、次のようになります。    static void swap(Integer * i, Integer * j) {      Integer * temp;      temp = i;      i = j;      j = temp;    }    static void swap(Foo * f1, Foo * f2) {      int temp;      temp = f1->i;      f1->i = f2->i;      f2->i = temp;    }

その他の回答 (1)

回答No.2

>Integerクラスが交換できない理由がわかりません. Integerクラスは immutable なので、値の変更はできません。 また swapは参照を別の変数に渡すだけで、また、Integer同士の代入は参照の 代入なので、結局、元のi, j が持つ参照は何も変わりません。

関連するQ&A

  • Integer クラスについて教えて下さい

     今晩は、java初心者です、宜しくお願いします。    Integerクラスについて下のように「i1 = new Integer("1");」と書いても「i2 = new Integer(1);」 と書いても、どちらも数字として認識されているようです。  正式な書き方としてはどちらなんでしょうか、宜しくお願いします。 ========================================================================= public class Test1 { public static void main(String[] args) { Integer i1 = new Integer("1"); System.out.println((i1+2)); Integer i2 = new Integer(1); System.out.println((i2+3)); } }

    • ベストアンサー
    • Java
  • クラスとインスタンスについて

    はじめまして。Javaをはじめて3か月の超初心者です。 早速ではございますが、質問をさせていただきます。 以下のサンプルで、 class Foo { private int i = 0; Foo(int i) { this.i = i; } void func1() { System.out.println(this.i); } void func2(Foo foo) { System.out.println(foo.i); } } class Main { public static void main(String[] args) { Foo obj1 = new Foo(100); Foo obj2 = new Foo(500); obj1.func1(); obj1.func2(obj2); } } privateフィールドのスコープは同一クラス内からしか アクセスできないと参考書には記述されているの ですが、そのクラス内に上のサンプルのように this.iやfoo.iというように、クラスは同じでも インスタンスが異なるものがiにアクセスするとき、 上のサンプルは、どちらもアクセス制限のエラーが表 示されません。なぜなのでしょうか? this.iというアクセスは、現在実行中のインスタン ス内でのアクセスなので、privateスコープ内での アクセスであるというような感じがするのですが、 foo.iというアクセスの方は、現在実行中のインスタンスとは異なるインスタンス内でのアクセスなので、 privateスコープからはずれているような感じがして なりません。

    • ベストアンサー
    • Java
  • privateスコープについて

    はじめまして。Javaの初心者です。 どうしてもわからないことがあります。 以下のコードを見てみてください。 ************************************************ final class Foo { private int a; Foo(int a) { this.a = a; } public int func(Foo f) { if(this.a <= f.a) { return 1; } else { return -1; } } } final class Demo01 { public static void main(String[] args) { Foo obj1 = new Foo(10); Foo obj2 = new Foo(20); System.out.println(obj1.func(obj2)); } } ************************************************ Fooクラスの2つの異なるインスタンスのフィールドの 値の比較は、funcメソッドの呼び出しによって行われるのですが、funcメソッドの中で、実行中のインスタ ンス(this)のaにアクセス(this.a)することができるこ とは理解できるのですが、実行中のインスタンスとは 異なるFooクラスのインスタンスのaにアクセス(f.a)し たときprivateアクセスのため、参照できないとはなら ないのは、なぜなのでしょうか?どうかご教授をお願 いします。

    • ベストアンサー
    • Java
  • コンパイラのバグ?それとも

    下のようなコードを書いて、たとえば java PossibleCompilerMalfunction Hello のように実行すると、 Hello と表示されることを期待していたのですが、 null と表示されてしまいます。 (JDK1.5を使っています) final String t = args[0]; の部分を final String t = "Hello"; のように書き換えると、 Hello と表示されます。 つまり、コンパイル時に「t」の値が決まっていなければ nullになってしまうようです。 これってコンパイラのバグでしょうか。 あるいは私の考えに間違いがあるのでしたら、 指摘していただけるとありがたいです。 public class PossibleCompilerMalfunction { public static void main(String[] args) { final String t = args[0]; MyClass mc = new MyClass() { void foo() { System.out.println(t); } }; } static abstract class MyClass { MyClass() { foo(); } abstract void foo(); } }

    • ベストアンサー
    • Java
  • final修飾子を使用した場合で

    お世話になっています。 finalクラスとfinalメソッドの利用目的の考え方を踏まえて、 id/passwordを「新規」、「更新」、「削除」したい場合で、 開発者側から判定してほしいのですが。 ※更新、削除が複数実行されることを考慮する dbへのユーザーの追加方法だけ、決定事項として実行する(finalメソッド) public class LoginAction { public static void main(String[] args) { User login = new Login("test","test"); //サブクラスを親クラスにインスタンス化する int key = 0; String id="test"; String password="test"; login.check(key, id, password); } } public class Login extends User { public Login(String id, String password) { super(id, password); } //処理判断 @Override public void check(int key, String id, String password) { if(key==0){ insertUser(id,password); }else if(key==0){ deleteUser(id,password); }else if(key==2){ updateUser(id,password); } } } public class User { public User(String id,String password) {} /** * ユーザーの追加(一件) */ public final void insertUser(String id, String password) { //DBに登録 } /** * ユーザーの削除(1件) */ public final void deleteUser(String id,String password) { //DBからデータ削除 } /** * ユーザーの更新(1件) */ public final void updateUser(String id, String password) { //DBの更新 } //処理判断 public void check(int key, String id, String password) { //サブクラスに預ける } } また、この時に、check()メソッドでどの処理かを判断し、メソッドのわたしているのですが、それをコンストラクタで渡したら、 無駄なロスが出そうな気がするのですが。 他に、サブクラスで設定し、親クラスにインスタンス化を実行すると、 何がいいのかがよくわかりません。 親クラスはサブクラスのデータを持っていて、そうすることで最終的に 親クラスから、サブクラスのデータが取れるという感じなのですが。 宜しくお願いします。

    • ベストアンサー
    • Java
  • final変数について

    はじめまして。 質問があります。 以下のコードをみてください。 ---------------------------------------------------------------- final class Demo01 { final static String str1 = null; public static void main(String[] args) { final String str2= null; for(int i=0;i<10;i++) { final String str3 = null; // str1 = "" + i; // コンパイルエラー // str2 = "" + i; // コンパイルエラー // str3 = "" + i; // コンパイルエラー final String str4 = "" + i; // OK } } } ---------------------------------------------------------------- str1からstr3までは、コンパイルエラーになるのは理解できるのですが、str4がコンパイルエラーにならない理由がわかりません。 どうかご教授お願いします。

    • ベストアンサー
    • Java
  • Integerについて

    class Sample5_7_Integer { /** * Integerクラスのメソッド */ public static void main(String[] args) { //String → int int i1 = Integer.parseInt(args[0]); //int型にすることにより計算可能 System.out.println(i1 + 100); //String → integer Integer i2 = Integer.valueOf(args[0]); System.out.println(i2); Integer i3 = new Integer(100); System.out.println(i2.equals(i3)); } } をEclipseで実行したところ、 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at benkyou.Sample5_7_Integer.main(Sample5_7_Integer.java:10) というエラーになってしまいます。 どなたか解決法をお願いします。

    • ベストアンサー
    • Java
  • メソッド

    public class Point{ public int x; public int y; public void swap(int s){ int x = s * y; y = s * x; this.x = x; } public void swap2(int s){ int x = s * y; y = s * this.x; this.x = x; } public static void main(String[] args){ Point pt = new Point(); pt.x = 3; pt.y = 4; pt.swap(2); System.out.println(pt.x + " " + pt.y); pt.swap2(3); System.out.println(pt.x + " " + pt.y); } } このプログラムでswapメソッドとswap2メソッドってどう違うんですか?

    • ベストアンサー
    • Java
  • 親クラスの初期化についてご教授ください

    javaの勉強を始めた者です。質問させてください。 以下のようなコードの、 親クラスの初期化をしている部分の挙動が、 うまく理解できません。 class p{ public int i = 3; public void foo(){}; } class c extends p{ public int i = 0; public void foo(){ System.out.print("foo "); } } public class b{ public static void main(String[] s){ p bar = new c(); // ←ここです bar.foo(); System.out.print(bar.i); } } 実行結果は「foo 3」です。 以下の点が理解できません。 ・なぜメソッドは子クラスのものが実行されるのに、プロパティは親クラスのものが表示されるのか? ・子クラスのコンストラクタを利用することで、いったいどのような挙動となるのか? オブジェクト指向の基礎を理解しれません・・・よろしくお願いします。

    • ベストアンサー
    • Java
  • 参照・値渡しについて

    下記プログラム(ソース1)を実行すると「1」という値が出力されます。しかし、2行目をprivate static int a;とすると「0」という値が出力されます。 オブジェクトは参照渡しで基本データ型は値渡しと思ったのですが、2行目の値をString型で行ったところ全く変更されていない値が出力されました。(ソース2) 一体どういうことでしょうか? 回答のほどよろしくお願い致します。 (ソース1) public class X{ private static int a[] = new int[1]; public static void main(String []args){ modify(a); System.out.println(a[0]); } public static void modify(int a[]){ a[0]++; } } (ソース2) public class X{ static String a = "a"; public static void main(String []args){ modify(a); System.out.println(a); } public static void modify(String a){ a = "b"; } }

    • ベストアンサー
    • Java