11525


次の例では、２つのコンストラクタがあるクラスを定義します。変数nameと変数ageには妥当な規定値がないので既定コンストラクタを他のクラスから呼びだすことはできません。したがって他のクラスから呼び出せないようにコンストラクタをprivateで宣言する必要があります。と説明されています。  
コードは

[code]

    class Person{
        String name;
        int age;
    
        public Person(String name , int age){
            this.name = name;
            this.age  = age;
        }
    
        private Person(){
    
        }
    }
    
    class PrivateConstructor{
        public static void main(String args[]){
            Person p1 = new Person("John", 30);
            System.out.println(p1.name);
            System.out.println(p1.age);
            //Person p2 = new Person();
        }
    }
    
[/code]

と書かれています。ここで

[code]

    Person p2 = new Person();
    
[/code]

が呼び出せないという意味がよくわかりません。

[code]

    class Person{
        String name;
        int age;
    
        public Person(String name , int age){
            this.name = name;
            this.age  = age;
        }
    
        private Person(){
    
        }
    }
    
    class PrivateConstructor{
        public static void main(String args[]){
            Person p1 = new Person("John", 30);
            System.out.println(p1.name);
            System.out.println(p1.age);
            Person p2 = new Person("Emily", 29);
            System.out.println(p2.name);
            System.out.println(p2.age);
            //Person p2 = new Person();
        }
    }
    
[/code]

とためしに書いてみたのですが問題なくできます。  
Person p2 = new Person();ではname
とageが記入されてないから当然でないのはわかるのですがprivateの役割についてが理解できません。  
ためしに

[code]

    private Person(){
    
    }
    
[/code]

の部分を書かないでやってみても問題なくできました。  
あってもなくても問題なくでるのにprivateを記述した理由や役割について教えてください。  
またeclipceで

[code]

    private Person(){
    
    }
    
[/code]

の部分についてコンストラクターpersonはローカルで使用されていませんとでているのですが  
どういった意味でしょうか  
よろしくお願い致します。


CC BY-SA 3.0
2015-06-19T09:41:27.857
11516
2015-06-20T12:02:19.827
2015-06-20T12:02:19.827
5519
10197
question
java
コンストラクタの修飾子について


最初のケースで

[code]

    Person p2 = new Person();
    
[/code]

が呼び出せないのはアクセスできるコンストラクタに該当するものが無いからですね。

> コンストラクタをprivateで宣言する必要があります

についてはちょっと分からないです（使わないなら不要な気がしますが）。

> コンストラクターpersonはローカルで使用されていませんとでているのですが  
>  どういった意味でしょうか

`private`で宣言しているため自クラス内（ローカル）からしかアクセスできないので、  
自クラスで使っていない = 不要なので削除しても良いのでは？  
となります。  
不要なコードを残さないためのIDEの親切機能の一つと考えて良いと思います（public,
protected等の場合、他クラスが使っている可能性があるので判断できない）。

デフォルトコンストラクタとアクセス修飾子について勉強すると理解が早まるのではないかと思います。  
参考として、Google検索で一番上に出たやつを貼っておきます。

[デフォルトコンストラクタ](http://www.javadrive.jp/start/constructor/index4.html)  
[アクセス修飾子](http://msugai.fc2web.com/java/permitmod.html)


CC BY-SA 3.0
2015-06-19T11:13:07.740
11523
2015-06-19T11:13:07.740
3516
11516
answer


まず、既定コンストラクタ（デフォルトコンストラクタ）について、

[code]

    class Person {
        String name;
        int age;
        void hey(){
            System.out.println("Hey!");
        }
    }
    
    class Sample1 {
        public static void main(String args[]){
            Person p1 = new Person();
            p1.hey();
        }
    }
    
[/code]

Personクラスにはコンストラクタがありませんが、  
インスタンスであるp1を作成し`hey`メソッドを使うことができます。  
これは、暗黙に、

[code]

    public Person(){
    }
    
[/code]

のようなコンストラクタが作成されるため問題無くインスタンスを作成できます。  
こういうのを既定コンストラクタ（デフォルトコンストラクタ）といいます。  
ここで、

[code]

    class Person {
        String name;
        int age;
        void hey(){
            System.out.println("Hey!");
        }
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
    }
    
    class Sample2 {
        public static void main(String args[]){
            Person p1 = new Person();
            p1.hey();
        }
    }
    
[/code]

のように名前と歳を設定するコンストラクタを書いたとすると、

> エラー: クラス Personのコンストラクタ Personは指定された型に適用できません

のようなエラーを起こします。  
コンストラクタが書かれたので、自動的にPerson()のようなデフォルトコンストラクタが作成されなくなったためです。  
なので、

[code]

    class Person {
        String name;
        int age;
        void hey(){
            System.out.println("Hey!");
        }
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
        public Person(){
        }
    }
    
[/code]

のように明示的にデフォルトコンストラクタ`Person()`を書いてやる必要があります。  
それで、

[code]

    class Person {
        String name;
        int age;
        void hey(){
            System.out.println("Hey!");
        }
        void info(){
            System.out.println("私の名前は" + name + "です。");
            System.out.println("年齢は、" + age + "です");
        }
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
        public Person(){
        }
    }
    
    class Sample2 {
        public static void main(String args[]){
            Person p1 = new Person();
            p1.info();
        }
    }
    
[/code]

のようにすると、

> 私の名前はnullです。  
>  年齢は、0です

のように表示されます。（参照型の既定値`null`と数値型の既定値0になっている）  
「妥当な規定値がないので既定コンストラクタを他のクラスから呼びだすことはできません」  
とは、こういう意味ですね。  
仮に

[code]

    public Person(){
        this.name = "名無し";
        this.age = -99;
    }
    
[/code]

のようにデフォルトの値を設定したとしても妥当な既定値とは言えません。（多分）  
（値が未設定なんだろうとはわかるでしょうけど。）  
この場合単にデフォルトコンストラクタ自体を削除してしまっても既に説明したようにエラーになりますけど、  
(既定)コンストラクタがないのではなくて、引数がないコンストラクタは(意味がないので)使用禁止ですよという意味で、他のクラスからアクセス出来ないようにprivate
修飾をします。  
ということです。（多分）  
実際に、

[code]

    private Person(){
        this.name = "名無し";
        this.age = -99;
    }
    
[/code]

のように変更すると、

> エラー: Person()はPersonでprivateアクセスされます

のように表示されて、デフォルトコンストラクタはあるけど他のクラスからは使えません、  
だから使おうとしてもエラーですよ。ということになります。


CC BY-SA 3.0
2015-06-19T11:29:27.573
11525
2015-06-19T11:38:58.757
2015-06-19T11:38:58.757
5044
5044
11516
answer


既に詳しく解説してる方が居るので短く説明します。  
privateやpublicはアクセス修飾子と言います、文字通り装飾したコンストラクタのアクセスを制限します。  
ここで言うアクセスは下記になります。  
クラス内のみで使用できるか(private)  
クラス外でも使用できるか(public)

[code]

    Person p2 = new Person();
    
[/code]

上記が呼び出せないのは引数の無いコンストラクタにprivateを装飾されていたからです。  
  

> 他のクラスから呼び出せないようにコンストラクタをprivateで宣言する必要があります。

これはプログラミングにおける作法の様な物で、引数のないコンストラクタを呼び出せない事により、常にクラスの変数値を指定させてクラスの状態を保つ役割があります


CC BY-SA 3.0
2015-06-19T12:19:50.660
11527
2015-06-19T12:19:50.660
10219
11516
answer