• ベストアンサー

Stringクラスは他のクラスとどう違う?

Objectクラスを抽象クラスとするサブクラスに Stringというクラスがあります。 ストリングオブジェクトの宣言は下記のようにします。 String[] url = new String[2]; ストリングクラスは以下のように宣言時に初期化が可能です。 String[] url = {"honyahonya.com","0"}; また、以下のような指定も出来ます。 this.method( new String[]{"honyahonya.com","0"} ); そこで質問ですが Stringとはなぜこのような扱い方ができるのですか? 他のクラスとは、例外的に扱いが違うだけなのですか? 初期化で指定した文字列はどのように解釈されて、どういう 扱いがされているのでしょうか? 普段はなんとも思わず使っていますが なんとなく気になりませんか・・・。

  • Java
  • 回答数4
  • ありがとう数4

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

  • ベストアンサー
回答No.4

Stringクラスは特別ですね。 ダブルクォーテーションで挟まれた文字列はそれだけでStringクラスのインスタンスとして扱われますし、『+』で連結していける、というような点も他のクラスとは異なります。 参照型変数でありながら、基本データ型変数のような利便性が提供されているんですね。 ただ、これはJava言語の仕様なので、自作クラスをこのように優遇することはできません。 例えば、どう頑張っても MyClass myClass = "abc"; のような形にする事はできません。 MyClass myClass = new MyClass("abc"); の形でなければなりません。 String型のこのような優遇はおそらく、プログラミングにおいて文字列を使う機会が圧倒的に多い事から規定された仕様なのでしょう。 String型は結構紆余曲折のあるクラスです。 以前は、文字列の連結を行う際には String st = "abc" st += "def" のような形は、使うことこそできるものの、『処理が遅くなる』という理由で推奨されませんでした。 文字列の連結を行う場合は、代わりにStringBufferクラスを使うように、というような説明がちょっと古いJavaの本やインターネット上の情報には出ていますね。 しかし現在では(1.5からだったかな?)、コンパイラの性能が上昇したらしく、むしろString型のまま連結していく事が推奨されています。 個人的には、桁の多い小数点計算でBigDecimalクラスを使わなければならない不便も改善して欲しいですね。

SAKENOSAKA
質問者

お礼

ご回答ありがとうございます。 もやもやしたものがスッキリしました。

その他の回答 (3)

回答No.3

この辺に詳しい解説があります。参考にしてください http://www.lcv.ne.jp/~kenmio/yomimono/yomimono103.htm http://www.nextindex.net/java/class/String.html

SAKENOSAKA
質問者

お礼

下段のページの API仕様 というアンカからリファレンスに 飛びましたが、その中の記述に 「Java 言語は、文字列連結演算子 ( + )、およびその他のオブジェクトから文字列への変換に対する特別なサポートを提供します。」 特別なサポートってありますね・・・。 何を指しているのかよく意味がわかりませんでしたが そのへん理解しないと駄目なんだろか。

  • m-oosgi
  • ベストアンサー率62% (10/16)
回答No.2

Javadocでは『String クラスは文字列を表します。Java プログラム内の「abc」などのリテラル文字列はすべて、このクラスのインスタンスとして実行されます。』と記載されています。 これで解決だと思いますが、以下に補足します。 >String[] url = {"honyahonya.com","0"}; はStringインスタンス"honyahonya.com"と"0"を初期化子としてString配列をインスタンス化しています。 >new String[]{"honyahonya.com","0"} は、明示的にString配列を宣言して、初期化しています。 これだけの違いです。インスタンス化する方法がいくつかあるという程度です。 また、String以外にも同様の手順でインスタンスを生成することが可能です。

SAKENOSAKA
質問者

お礼

すみません、質問の例については自分の誤りに気づきました。 確かに、他のクラスでも同様に生成できますね・・・。 例えば、Stringクラスと同じ働きのクラスを 自作することって可能なんでしょうか? Stringクラスについて特殊性が あるのか、ないのかが知りたい内容です。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>Stringとはなぜこのような扱い方ができるのですか? >他のクラスとは、例外的に扱いが違うだけなのですか? どう扱いが違うと思っておられるのか良くわかりません。 例として挙げられているのが String の配列になっていますが、何か意図があるのですか? 単純に文字列リテラル "honyahonya.com" が String のコンストラクタに与えられることがわからないということではないんですよね?

SAKENOSAKA
質問者

お礼

すみません、質問の仕方がおかしかったです。 根本的に私は上級プログラマではないので 理解が途切れ途切れのところがあります。 扱いとして分からなかったのが String url = "honyarara.com"; と、した場合に url自体 が設定した文字列を 現せることが不思議に感じています。 コンストラクタに与えた文字列に対して url.toString();で現すというなら分かりますが urlとしただけでも文字列を表現できる点が 特殊で例外的なクラスなのかと思いました。

関連するQ&A

  • 【C#】フォームクラスと他クラスとの連携について

    C#を勉強し始めたばかりの者です。 オブジェクト指向言語が初めてなので、オブジェクト指向的考え方が出来てないゆえの質問だとは思うのですが・・・。 質問内容ですが、フォームクラスと他のクラスとの連携方法がわかりません。 具体的に言いますと、フォームクラスで別のAというクラスを宣言し、そのクラスのB()メソッドを実行したときに中で発生した例外メッセージをフォームのコントロールで表示したい、という場合、どうすればよいのでしょうか? Doメソッドで例外メッセージをstringとして返し、それをフォームクラスの方で処理するしかないのでしょうか? お知恵を貸してください。よろしくお願いします。

  • 抽象クラスのオブジェクトを生成できない理由は?

    ・抽象クラスは、なぜ(オーバーライドしないと)オブジェクトを生成できないのでしょうか? ・インタフェースみたいに、抽象メソッドしか宣言することができないなら話は分かるのですが… ・抽象メソッドでない普通のメソッドを実装できるのなら、オブジェクトを生成してくれても良いと思うのですが… ・そういう問題ではない?

    • ベストアンサー
    • Java
  • Stringクラスのlengthメソッドについて

    こんにちは、Stringクラスのlengthメソッドについて質問させてください。 今まで配列のlengthは、宣言時に長さが決定するからメソッドではなく、finalフィールドで十分。 ArrayListだとかは長さが変わるからメソッドという意識を持っていました。 (カプセル化の概念とも関わりますが) 先日その話しをしていたら、「でも文字列(Stringオブジェクト)の長さも不変だよね。」と言われました。 確かに文字列の長さは不変なのに、長さの取得にはメソッドを使っています。 言語仕様として一貫性を持たせるなら、配列もlengthメソッドにするか、文字列をlengthフィールドにしたほうが綺麗だと思うんです。 Stringクラスのソースコードを見ていたら、文字列の長さは内部的に private int count; と宣言されていました。 そして、lengthメソッドは return count; しているだけでした。 ただ、このcountフィールドに値を代入しているのはコンストラクタ内だけだったので、 public final int length; とすれば、良かったのでは?と思いました。 この考えについて、 それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。 よろしくお願致します。

  • スーパークラスとサブクラスについて

    Parent pc = new Children(); pc.getName(); 下記、2つのクラスがある状態で上記のようにしてgetName()を実行したところ サブクラスのgetName()が呼ばれました。このことからpcオブジェクトの実態はChildrenクラス なのだと理解していたのですが、サブクラスにしか存在しないメソッドを呼ぼうとして pc.getChildName()と記述したところコンパイルエラーになってしまいました。 pc.getParentName()となら記述することができるのですがpcオブジェクトのをどう理解すれば よいのでしょうか。 【親クラス】 public class Parent { public void getName() { System.out.println("Parent"); } public void getParentName() { System.out.println("親クラス特有のメソッド"); } } 【サブクラス】 public class Children extends Parent{ @Override public void getName() { System.out.println("Children"); } public void getChildName() { System.out.println("サブクラス特有のメソッド"); } }

    • ベストアンサー
    • Java
  • メソッド宣言内でクラス名が書かれる理由

    public static void main(String arg[]){ 上記は、メソッド宣言ですが、このメソッド宣言の中に書かれているStringは、「標準クラスの1つ」だと聞いています。(標準クラスの意味さえ僕はわかりませんが、、参考書に書かれてあるのを見てもチンプンカンプン) 何故Stringは標準クラスの1つなのに、メソッド宣言の中に書かれているんですか? 質問1:私の仮説では、メソッドがどこのクラスに属するかを明示するためにメソッド宣言内にStringが書かれていると考えてます。それでよろしいですか? 質問2:メソッド宣言とは本質的にどういうことですか?プログラミング初心者の僕でもわかるように解説お願いします。

    • ベストアンサー
    • Java
  • 抽象クラスとオブジェクトを格納する配列(java)

    独習java第4版でわからない所があります。 abstract class Widget { String color; abstract int getMass(); public String toString() { return getClass().getName() + ": " + color + ", " + getMass(); } } class WidgetA extends Widget { final static int MASS = 4; WidgetA(String color) { this.color = color; } int getMass() { return MASS; } } class WidgetB extends Widget { final static int MASS = 1; WidgetB(String color) { this.color = color; } int getMass() { return MASS; } } class WidgetC extends Widget { final static int MASS = 5; WidgetC(String color) { this.color = color; } int getMass() { return MASS; } } class WidgetD extends Widget { final static int MASS = 17; WidgetD(String color) { this.color = color; } int getMass() { return MASS; } } class WidgetTypes { static int NUMWIDGETS = 6; public static void main(String args[]) { // 部品を格納する領域を宣言して割り当てる Widget widgets[] = new Widget[NUMWIDGETS]; // 部品を作成する widgets[0] = new WidgetC("Red"); widgets[1] = new WidgetA("Green"); widgets[2] = new WidgetD("Yellow"); widgets[3] = new WidgetB("Magenta"); widgets[4] = new WidgetA("Black"); widgets[5] = new WidgetC("White"); // 部品を処理する int totalMass = 0; for(int i = 0; i < NUMWIDGETS; i++) { Widget w = widgets[i]; System.out.println(w); totalMass += w.getMass(); } // 総重量を表示する System.out.println("Total mass = " + totalMass); } } これはある問題の解答ですが、僕にはどうしても理解出来ない部分があります。 mainのforループ内で Widget w = widgets[i]; totalMass += w.getMass(); となっています。 この仕組がわかりません。 まず Widget w = widgets[i] でWidget型の変数wにWidget型のwidget[i]を代入しているのにw.getMass()がエラーにならない理由がわかりません。(Widgetクラスは抽象クラスなのにwがWidgetクラスのインスタンスになっている?) これは 抽象メソッド( abstract int getMass() ) があるためでしょうか? ちなみにWidgetクラスとそのサブクラスからこの抽象メソッドを削除したらコンパイルエラーが出ました。 ではなぜ抽象クラスの抽象メソッドから、そのサブクラスのメソッドまで範囲が伸びるのでしょうか? どういう仕組でしょうか? この質問を書きながら思ったのですが、どうも配列の仕組みや抽象クラス・メソッドの仕組み、「オブジェクト」と「インスタンス」の違いがよくわかってないようです。 多分問題の本質はそこにあると思うんです。 駄文で申し訳ないです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • インスタンス化について(ポリモーフィズムについて)

    Java初心者です。 Javaの書籍で、ポリモーフィズムを説明している箇所において オブジェクトを生成する際に、以下のような書き方をしているのを見ます。 1.----- スーパークラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); -------- 上記は、 何を実現する為に、左辺と右辺のクラス名とコンストラクタ名を変えているのでしょうか? (もちろん詳細は実際に書かれたメソッドや変数によると思いますが、一般的な話として。) また併せて、 2.----- サブクラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); ------- と書いた時とでは、使用(アクセス)出来るメソッドや変数、 生成されたオブジェクトの中身が、どのように変わってくるのでしょうか? 2.の方法では、何が実現出来ないのでしょうか? 教えて下さい!

    • ベストアンサー
    • Java
  • データベース(テーブル情報)操作方法に関して

    まだJAVAを初めて1ヶ月ちょいの初心者です。ぜひ教えて頂きたいことがあります。 データベースのテーブル操作に関してなんですが、どうコーディングしたら効率のよいプログラムになるのか検討段階でつまずいています。 今考えているのが、スーパークラスにてテーブルの各カラム変数を宣言し、そのサブクラスにてテーブル操作毎のSQL発行(スーパークラスから継承した抽象メソッドを用いて)をしたほうがいいのかなと考えてます。 つまり・・・ ----<<super class(抽象クラス)>>----- public abstract class InfoTable { private String name; private int age; : public String getName() { return Staff_ID; } public String setName(String name){ this.name = name } //抽象クラス(SQLを発行しテーブルを操 //作する抽象メソッド) public abstract boolean exec(); } とし、サブクラスにて継承&実装すればよいのかと・・・。 実際にテーブルのカラムが多くなれば、setter・getterを多く繰り替えし処理をしなければならなくなり、それは大変だし、プログラム的にもよくないんじゃないかと考えています。実際にサブクラスはサーブレットからデータを取得してから処理を行う予定なので、Vectorを使えばいいのかなとは思いますが、どう使ったらよいのか検討がつきません。 長々と書いてしまい申し訳ございません。 どなたか良い知恵をお貸し下さい!

    • ベストアンサー
    • Java
  • サブクラスからメインメソッドの値を参照するとき

    サブクラスからメインのメソッドを参照する時にメインプログラムが二重起動してしまってどうしたらいいのかわかりません。 プログラムは メインクラスが public class MainProg{ 初期定義など public MainProg() {    プログラム中身 } public String Month{ return A; } public static void main(String [] args) { new MainProg(); } } サブクラスが public class Transmission{        一部省略 MainProg main = new MainProg(); String Month = main.Month(); } このようになっているんですが メインクラスで使用している値をサブクラスで参照しようとしたときにメインクラスがもう一度呼び出されてしまいます。 どのようにしたらいろいろ操作してみたんですが、どうにも解決法がわかりません。 お願いします。

  • サブクラス型オブジェクトをスーパークラス方に代入

    ある所で下記のような継承についての記述をみつけました。 ----------------------------------------------------------------------------- 継承の目的は、あるクラスで実装したメソッドなどの機能を利用して、 さらに実装を追加する差分コーディングです。 一つのクラスから複数のサブクラスを作ることも良くあります。 このような時、それらのサブクラス型オブジェクトの参照を代入できる変数として、 スーパークラス型変数を使うことがしばしばあります。 ----------------------------------------------------------------------------- サブクラス型オブジェクトの参照を代入できる変数として、 スーパークラス型変数を使うことがある、と いうのはどういった場合に使うのでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう