外出自粛中でも楽しく過ごす!QAまとめ>>

ワイルドカード<?>と型パラメータ<T>の違いがすっきりしない。

現在、Javaを勉強中の初心者です。一応、Cの心得はあります。
とりあえず、SJC-P資格の取得を目的として勉強していますが、どうも<?>のワイルドカードがすっきりと理解できません。というのも、Generics表記である<T>との違いが明確に区別できずにいるからです。

例えば、下のサンプルプログラムを例として、<T>と<?>の使い分けは、どのように頭を整理すればよいのでしょうか?

Java初心者ゆえ、できるだけ難しい言葉は使わずに教えていただけると幸いです。


----------------------------------------------------
class WildCardSample1<T>{
private T type;
public WildCardSample1(T type){
this.type = type;
}
public void setType(T type){
this.type = type;
}
public T getType();
return type;
}
class WildCardSample1Main{
static void disp(WildCardSample1<?> w){
System.out.println(w.getType());
}
public static void main(String[] args){
disp(new WildCardSample<String>("Tiger"));
disp(new WildCardSample<Double>(5.0));
}
}

このQ&Aに関連する最新のQ&A

A 回答 (2件)

<T>とか<E>というのはジェネリックスのクラスやメソッドを宣言する時に使うもので、


ワイルドカードの<?>は引数や変数、戻り値型などの参照の宣言にしか使えません。

つまり上のコードで言えば、

class WildCardSample1<T>{

のかわりに

class WildCardSample1<?>{

のようなコードは書くことができないということです。

<?>は単に任意の型を代入できますということをあらわしているだけです。

List<?> l = new ArrayList<String>();
は出来ますが、

List<T> l = new ArrayList<String>();
は出来ません。

Tは何のクラスになるか分からないので、Stringではエラーになります。
    • good
    • 5

List を例にして、よく見る Generics のパターンを整理すると↓こんな感じになります。



■ List<String>
  → 文字列の格納が出来るリスト。

 入れられるもの : 文字列(String)とnull
 取出されるもの : 文字列(String)かnull


■ List<Object>
  → どんな型のオブジェクトの格納も出来るリスト。

 入れられるもの : 任意の型のオブジェクトとnull
 取出されるもの : Object型のオブジェクト(=任意の型のインスタンス)かnull


■ List<?>
  → 何かの型のオブジェクトの格納が出来るリスト。その型が何かは分からない。

 入れられるもの : null (入れられる型が分からないため)
 取出されるもの : Object型のオブジェクト(=何かの型のインスタンス)かnull


■ List<T>
  → T型のオブジェクトの格納が出来るリスト。Tはそれぞれのクラス宣言・メソッド宣言で指定される。(コンパイラが判断できる場合は暗黙に指定される場合も有る)

 入れられるもの : T型のオブジェクトとnull
 取出されるもの : T型のオブジェクトかnull


下記の様に渡された WildCardSample オブジェクトから type を取出して返すメソッドを考えます。
----------------------------------------------
class WildCardSample1Main2{

static <T> T getType1(WildCardSample<T> w){
return w.getType();
}

static Object getType2(WildCardSample<?> w){
return w.getType();
}

public static void main(String[] args){

String typeStr1 = getType1(new WildCardSample<String>("Tiger"));
Double typeDouble1 = getType1(new WildCardSample<Double>(5.0));

Object typeStr2 = getType2(new WildCardSample<String>("Tiger"));
Object typeDouble2 = getType2(new WildCardSample<Double>(5.0));
}
}
----------------------------------------------
getType1 では引数の宣言が <T> なので、そのT型のオブジェクトを返せます。
getType2 では引数の宣言が <?> になっているため Object 型のオブジェクトを返すしか有りません。
getType1 の戻り値は、 main 内でキャストしなくても、String や Double 型の変数に代入できています。


下記のページも参考になると思います。
http://www.ibm.com/developerworks/jp/java/librar …
http://www.ibm.com/developerworks/jp/java/librar …
http://www.ibm.com/developerworks/jp/java/librar …
    • good
    • 5

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QjavaのジェネリックスでTとEの違いが良く分かりません。

javaのジェネリックスでTとEの違いが良く分かりません。
参考書に
「E」は(Element:要素)
「T」は(Type:型)
と書いていますが、この二つの使い分けが良く分かりません。

「Eに入るのが要素なら、要素ってコレクションのオブジェクトことで…でもオブジェクトは型から作るからTで…どっちを使えばいいか分からない orz」

インターネットで調べると「T」はテンプレート?

と、こんがらがってます。プログラムに関して全くの素人で、基本的な考え方がしっかりしていないので、おかしいことを聞いてるのかもしれませんが、どなたかよろしければ回答お願いします。

Aベストアンサー

「T」「E」などの型パラメータ名は、コンピュータにとっては何であっても違いは有りません。変数名などと同様です。(もちろん「for」などの予約語は使えませんが。)
動作さえすれば良いのであれば、「HOGE」などでもかまいません。

例) public <HOGE> HOGE name(HOGE h) { ・・・・・ }

ですが、「HOGE」などでは書いた人の意図が分からず、プログラムが理解しづらくなります。
ですので、(未来の自分も含めた)そのプログラムを読む人が分かりやすいようなものにするのが定石です。

標準ライブラリで例を挙げると、下記の様になっています。

・ java.util.Collection<E> の場合は要素(Element)の型を指定するので「E」
・ java.util.Map<K,V> の場合はキー(Key)と値(Value)の型を指定するので「K」「V」

標準ライブラリでも、単純な概念に当てはまらない場合などは「T」としているようですが、「T」という名前は「これは型パラメータですよ」ということしか表現していません。他に適切な名前があれば、そちらにした方が良いでしょう。
ただし、ぱっと見て型パラメータである事が分かるという意味では「HOGE」などよりは良いです。

参考URL:http://www.javainthebox.net/laboratory/J2SE1.5/LangSpec/Generics/Generics.html

「T」「E」などの型パラメータ名は、コンピュータにとっては何であっても違いは有りません。変数名などと同様です。(もちろん「for」などの予約語は使えませんが。)
動作さえすれば良いのであれば、「HOGE」などでもかまいません。

例) public <HOGE> HOGE name(HOGE h) { ・・・・・ }

ですが、「HOGE」などでは書いた人の意図が分からず、プログラムが理解しづらくなります。
ですので、(未来の自分も含めた)そのプログラムを読む人が分かりやすいようなものにするのが定石です。

標準ライブラリで例を挙げ...続きを読む

Qinterface,extend,implementのちがい

お世話になります、

Javaを勉強しているのですが、
interface,extend,implementの使い分けがわかりません。

私の解釈としては、
(1)interfaceは、グローバル変数の定義、グローバルメソッドの定義(実装はしない)。

(2)extendは、extendクラスを親クラスとして親クラスの機能を使用できる。

(3)implementは…,implementもextendと同じような意味だと解釈しているんですが、違う点は、implementで定義してあるメソッドは、使用しなくても、実装しなければならないという点でしょうか?

とにかくこの3つのを使い分けるコツとかあれば教えてください。
よろしくお願いします。

Aベストアンサー

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば、getStringLength()メソッドなどが
あったほうが良いでしょうか。
このgetStringLength()メソッドは、2バイト文字も1バイト文字も「1文字」
と数えてくれると言う点で、まさに、日本語クラス用のメソッドだと言えるでしょう。

例えば、Java的に記述すると、、、
class Japanese {
public int getStringLength() {
  ・・・
return strlength;
 }
 ・・・
}

class TextField {
・・・
}

class JTextField extends TextField, extends Japanese {
・・・・
}

C++ではそのように実装するでしょう。
しかし、Javaにはこのような高度な機能はありません。

そこで、生まれた苦肉の策が、「interfaceとimplements」です。

interface Japanese {
public int getStringLength(); // interfaceは実装を含まない!
                 // すなわち「実装の継承」ができるわけではない。
}

class TextField {
・・・
}

class JTextField extends TextField implements Japanese {
・・・・
public int getStringLength() {
  ・・・
return strlength; //implementsの実装を「各クラスで」実装してやる必要がある。
 }
}


結局のところ、Javaでは、複数のクラスを親クラスには持ち得ないため、継承できなかったクラスは「各クラスで実装してやる必要性」があるのです。


ではどのように使うのが効果的か?

なまえのままです。「代表的なインターフェイス」にたいしてinterfaceを使うのが良いと思います。

例えば、プレイヤー系であれば、ビデオ・コンポ・ウォークマン・などにかかわらず、
interface controlpanel {
public play();
public stop();
public next();
public back();
}
というような基本的インターフェイスを「持っているべき」です。

こうすることで、それぞれのクラス宣言の際に、これらの「インターフェイスを持っているべきであり、実装されるべきである」ということを「強く暗示」することができます。
class videoplayer extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

こうすることで、同様のクラスを作成するユーザーは、
「プレイヤー系は、4つ操作が出来るコントロールパネルをインターフェイスとして持つべきなのだな!?」という暗示を受け取り、自分のクラスでもそれを模倣するでしょう。

class mp3player extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

また、これらのクラスを使用するユーザーも、「implements controlpanel」という
表記を見て、「4つの基本操作は押さえられているのだな!」という基本中の基本動作を抑えることが出来ます。

まとめると、クラスに「こういう特徴もたしてください!」「こういう特徴持ってますよ!」という一種の暗示的警告や方向性を与えることができるわけですね。

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば...続きを読む

QJAVA  ArrayListからArrayListへのコピー

java で、ArrayListからArrayListへコピーはできるのでしょうか?
clone()というメソッドがありましたが、よくわからず、コピーできてないようなので伺いました。

ベーシックではできるようですが、JAVAでもできるのでしょうか?
どなたか教えていただけませんでしょうか?

Aベストアンサー

ArrayList li = new ArrayList(list);
でよいでのでは?

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

Qyyyymmddからyyyy/mm/ddへの変換

いつもお世話になっております。
Aと言う変数にはyyyymmddの値が入っていて
Aをyyyy/mm/ddにしてBの変数に入れたい場合の処理がわかりません。
調べたところ、SimpleDateFormatクラスと言うものを使えばよいと言うことが判明しました。
しかし、今まで使ったことがないのでよくわかりません。
変数Aと変数BはどちらもString型です。
ご教授お願い致します。

Aベストアンサー

 こんにちは。

 本当に変数aの中の文字列が厳密にyyyyMMddの形式のなっているのなら、普通に

String b = a.substring(0, 4) + "/" + a.substring(4, 6) + "/" + a.substring(6, 8);

 これでいいと思いますが、いったんDate型にする必要があったり、ちゃんと日付として認識できるか確かめる必要がある場合は、

String a = "20051029";

SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateInstance();
formatter.applyPattern("yyyyMMdd");
try {
  Date date = formatter.parse(a);
  formatter.applyPattern("yyyy/MM/dd");
  String b = formatter.format(date);
  System.out.println(b);
}
catch (ParseException ex) {
  System.out.println("解析失敗");
}

 こんな感じでいいんじゃないでしょうか。

 こんにちは。

 本当に変数aの中の文字列が厳密にyyyyMMddの形式のなっているのなら、普通に

String b = a.substring(0, 4) + "/" + a.substring(4, 6) + "/" + a.substring(6, 8);

 これでいいと思いますが、いったんDate型にする必要があったり、ちゃんと日付として認識できるか確かめる必要がある場合は、

String a = "20051029";

SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateInstance();
formatter.applyPattern("yyyyMMdd");
try {
  Date date = formatter.p...続きを読む

Qシンボルが見つかりませんというエラーが理解できません。

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Image[3];
Thread t;
int index1 = 0;
int index2 = 0;
String msg = "";
String msg1 = "";

boolean state = false;
Button b1 = new Button("ぐー");
Button b2 = new Button("ちょき");
Button b3 = new Button("ぱー");

public void init(){
for(int i = 0; i<=2; i++){
img[i] = getImage(getDocumentBase(),"hanabi" + (i+1) + ".JPG");
}
add(b1);
add(b2);
add(b3);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
msg1 = "結果は・・";

}

public void paint(Graphics g){
g.drawImage(img[index1],350,30,this);
g.drawImage(img[index2],695,30,this);
g.drawString("コンピューター",420,300);
g.drawString("あなた",800,300);
g.drawString(msg,630,320);
g.drawString(msg1,550,320);
}

public void start(){
state = true;
t = new Thread(this);
t.start();

}

public void run(){
while(state){
index1++;
if(index1 == 3){
index1 = 0;
}
index2++;
if(index2 == 3){
index2 = 0;
}
repaint();
try {
Thread.sleep(60);
}catch(InterruptedException e) { }
}
}

public void actionPerformed(ActionEvent e){
if(state == false) {
start();
return;

}
state = false;
if(e.getSource() == b1) {
msg = "ぐー";
index2 = 0;
}

else if(e.getSource() == b2){
msg = "ちょき";
index2 = 1;
}

else if(e.getSource() == b3){
msg = "ぱー";
index2 = 2;
}
check();
repaint();
}

public void check() {
if(index1 == index2) msg ="あいこ";


else if (index1 == 0) {
if(index2 == 2) msg="あなたの勝ち";
else msg ="あなたの負け";
}

else if(index1 == 1) {
if(index2 == 0) msg="あなたの勝ち";
else msg="あなたの負け";
}

else if(index1 == 2) {
if(index2 == 1) msg="あなたの勝ち";
else msg="あなたの負け";
}

}
}

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Imag...続きを読む

Aベストアンサー

「シンボルを見つけられません。」というエラーの下に何か表示がありませんでしたか?そこにヒントがあると考えられます。
シンボルを見つけられませんといエラーが表示される主な理由は4つあります。
(1)クラス、メソッド、変数などの綴りミスや定義していない変数を使用している可能性がある。
(2)コンストラクタを呼び出すときに、newを忘れている可能性がある。(3)公開されていないメンバーを呼び出している可能性がある。
(4)必要なimport文を記述し忘れている可能性がある。
ここでのあなたのエラーは(1)番ではないでしょうか?上記ではimageとなっている変数がimgになっていますね。
これはエラー表示をよく見ることで意外と簡単に解決できるのです。
ゆっくり丁寧にエラー表示を見るように心がけることが大事ですよ。

Qjava spring でエラーが出て困ってます

spring 超初心者です。cloudfoundyでcronを実行しようとしています。

CronService から@Autowiredで、StartJob_cを呼び出し
更に呼び出されたStartJob_cから、@AutowiredでReadFile_cを呼び出そうとしています。

しかし、Injection of autowired dependencies failed; nested exception
というエラーが出て動きません。

質問1)このような、呼び出しはできないのでしょうか?
質問2)springでこのような、呼び出しをしたい場合、どうするのが良いのでしょうか?




エラー内容は、
[ERROR] [main 11:08:03] (ContextLoader.java:initWebApplicationContext:220) Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cronService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.krams.tutorial.job.StartJob org.krams.tutorial.job.CronService.startJob; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'syncStartJob': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.krams.tutorial.job.ReadFile org.krams.tutorial.job.StartJob_c.readFile_cService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.krams.tutorial.job.ReadFile] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

です。


ロジックサンプルは、以下の通りです。

@Service
public class CronService implements Cron{

protected static Logger logger = Logger.getLogger("service");

@Autowired
@Qualifier("syncStartJob")
private StartJob startJob;

@Scheduled(cron="*/10 * * * * ?")
public void doSchedule() {
logger.debug("cron");
startJob.jobExec();

}
}




@Component("syncStartJob")
public class StartJob_c implements StartJob{
protected static Logger logger = Logger.getLogger("service");

//@Autowired
//private StartJob2 startJob2_cService;

@Autowired
private ReadFile readFile_cService;
@Autowired
private DeleteFile deleteFile_cService;
@Autowired
private ShinchokuFile1LineDel shinchokuFile1LineDel_cService;

public void jobExec() {
// TODO Auto-generated method stub
logger.debug("StartJob");

List<String> strYMDStartArray = new ArrayList();
strYMDStartArray.add("20060701");//0 1
strYMDStartArray.add("20060501");//1 2
strYMDStartArray.add("20060301");//2 3
strYMDStartArray.add("20060101");//3 4
strYMDStartArray.add("20051101");//4 5
strYMDStartArray.add("20050901");//5 6

String strFileName = "";


List<Integer> AYMDCNTData = new ArrayList();
strFileName = "YMDCNT";
AYMDCNTData = this.readFile_cService.readIntData(strFileName);
int intYMDCNT = AYMDCNTData.size();



List<Integer> ACNTData = new ArrayList();
strFileName = "JobCNT";
ACNTData = this.readFile_cService.readIntData(strFileName);
int intJobCNT = ACNTData.size();




String strYMDStart = "";
String strYMDEnd = "";
int intYMDID = 0;
int intJobCounter = 11;
intJobCounter = intJobCounter + intJobCNT;

String sTrailJoken_start = "";
String sTrailJoken_end = "";
String sTrailGaku_start = "";
String sTrailGaku_end = "";

if( intJobCounter == 11){
sTrailJoken_start = "10";
sTrailJoken_end = "10";
sTrailGaku_start = "5000";
sTrailGaku_end = "5000";
}else if(intJobCounter == 12){
sTrailJoken_start = "10";
sTrailJoken_end = "10";
sTrailGaku_start = "10000";
sTrailGaku_end = "10000";
}else if(intJobCounter == 13){
sTrailJoken_start = "10";
sTrailJoken_end = "10";
sTrailGaku_start = "15000";
sTrailGaku_end = "15000";
}else if(intJobCounter == 14){
sTrailJoken_start = "10";
sTrailJoken_end = "10";
sTrailGaku_start = "20000";
sTrailGaku_end = "20000";
}

spring 超初心者です。cloudfoundyでcronを実行しようとしています。

CronService から@Autowiredで、StartJob_cを呼び出し
更に呼び出されたStartJob_cから、@AutowiredでReadFile_cを呼び出そうとしています。

しかし、Injection of autowired dependencies failed; nested exception
というエラーが出て動きません。

質問1)このような、呼び出しはできないのでしょうか?
質問2)springでこのような、呼び出しをしたい場合、どうするのが良いのでしょうか?




エラー内容は、
[ERROR] [main 11:08:03] ...続きを読む

Aベストアンサー

例外のログはこれだけじゃないですよね?

Qequalsの逆

javaで、文字列の場合は比較演算子の「==」は用いずに

if ((str1.getText()).equals(str2)){
(※…str1,2は文字列)

と書きますよね?
この逆で、文字列str1とstr2は等しくないとき、にはif以下の条件文をどのように書けばよいでしょうか?

Aベストアンサー

>if !((str1.getText()).equals(str2)){

あくまで
if(){
}


!(str1.getText()).equals(str2)
が入っているので
if !((str1.getText()).equals(str2)){
じゃなくて
if (!(str1.getText()).equals(str2)){
こう。

QJavaで文字列をゼロ埋め(ゼロパディング)

Javaで文字列を前ゼロで埋め(ゼロパディング)たいのですが、
exceptionが発生してうまくいきません。
だれかお助け頂けたら助かります。

(例)123の前に0を5つ結合したい場合、

String str2="123";
String str = String.format("%08s",str2);

で問題無いと思ったのですが、
exceptionが発生してしまいます。

回答お待ちしております。

Aベストアンサー

そのExceptionはどういったExceptionなのか把握されてますか?
何が悪いのかの理由もそのExceptionからわかると思いますが。

http://docs.oracle.com/javase/jp/6/api/java/util/Formatter.html#syntax
をよく読んで"%08s"という指定ができるのかどうか確認しましょう。

やられたいことは"123"の先頭に"00000000"をつけて後ろから8文字取り出せばできると思いますが。

Qflush()とclose()について

Javaを独習Javaで独習しています。現在、入出力の所まできたのですが、Writerクラスのclose()とflush()の違いがわかりません。それぞれのメソッドの意味はわかるのですがそれらを使う目的がわかりません。flush()は「バッファ付けデータをそのストリームで表されている物理デバイスに書き込む」とあるのですが、サンプルには(バッファ付け文字ストリームの単元にも)flush()は一度も出てこずclose()のみで書き込みが行われています。探したのですが独習Javaのサンプルの中には結局flush()は一度も出てきませんでした。この二つの違いはなんなのでしょうか?初心者のためわかりにくい質問かとは思いますがよろしくお願いします。

Aベストアンサー

フラッシュすれば、ファイルやその他物理デバイスに強制的にバッファの内容が出力されるということは、理解されていると考えてよいですね?

で、なかなかストリームをクローズできない(またはしない)場合には、いつまで経ってもバッファの内容が物理デバイスに出力されないかも知れませんよね?でも、適当なタイミングで定期的にフラッシュすれば、その時点でバッファに溜まっている内容が物理デバイスに出力されます。

そのサンプルの場合は、書き出してすぐ?クローズしちゃうため、明示的なフラッシュは必要なかったんだと思いますが、

・フラッシュは、(ストリームを閉じずに)バッファの内容を強制的に物理デバイスに出力する。
・クローズは、(フラッシュされていなければフラッシュしてから)そのストリームを閉じる。

とまぁ、目的も内容も全然違うわけです。


人気Q&Aランキング