javaコマンドで"エラー:メイン・クラスorg.macho.Mainが見つからなかったかロードできませんでした。"とエラーが出る。
はじめに
いつもjavaのプログラムを書いたときはeclipseから実行していて、恥ずかしながらコマンドラインからjavaコマンドで実行することがほとんどありませんでした。今回、java.io.Consoleを使ったプログラムを実行するのにjavaコマンドで実行する必要があったのですが、いざjavaコマンドで実行すると上手くいきませんでした。その問題の解決策を調べても直接の解決策がなかなか見つかりませんでした。同じ問題に直面した方の参考になればと思い、この記事にEclipseで作成したjavaファイルをコンパイルし実行する方法を残そうと思います。
java経験をお持ちの方には当然のことを記述しているように感じると思います。悪しからずご容赦ください。
前提
- Eclipse 4.0
- jdk1.8.0
- iOSX
事象
以下のようなプログラムを作成し、javacコマンドでコンパイルしjavaコマンドで実行しようとすると、以下の例のようにエラーメッセージが出ます。
/Users/*****/work/eclipse/Test/TestProject ┗ org ┗ macho ┗ Main.java
package org.macho; public class Main { public static void main(String[] args) { System.out.println("main"); } }
次のようにjavaコマンドを実行しましたが、できませんでした。
# 前提としてカレントディレクトリは以下でした。※ユーザー名は*で伏せました。 *****-no-MacBook-Air:macho **********$ pwd /Users/**********/work/eclipse/Test/TestProject/src/org/macho *****-no-MacBook-Air:macho **********$ ls Main.java # コンパイル *****-no-MacBook-Air:macho **********$ javac Main.java # javaコマンド *****-no-MacBook-Air:macho **********$ java Main エラー: メイン・クラスMainが見つからなかったかロードできませんでした
他にも、classpathオプションを指定するなどいろいろやってみましたが結果は変わらず。
*****-no-MacBook-Air:macho **********$ java org.macho.Main エラー: メイン・クラスorg.macho.Mainが見つからなかったかロードできませんでした *****-no-MacBook-Air:macho **********$ java -classpath /Users/**********/work/eclipse/Test/TestProject/src/org/macho Main エラー: メイン・クラスMainが見つからなかったかロードできませんでした *****-no-MacBook-Air:macho **********$ java -classpath /Users/**********/work/eclipse/Test/TestProject/src/org/macho org.macho.Main エラー: メイン・クラスorg.macho.Mainが見つからなかったかロードできませんでした
もちろん、javaのパスは通っていました。(java - versionで確認)
*****-no-MacBook-Air:macho **********$ java -version java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
解決策
以下のように、【プロジェクト(ここではTestProject)】/srcまで移動してからjavaコマンドを実行すると成功しました。
*****-no-MacBook-Air:macho **********$ cd ../../ *****-no-MacBook-Air:src **********$ pwd /Users/**********/work/eclipse/Test/TestProject/src *****-no-MacBook-Air:src **********$ java org.macho.Main main *****-no-MacBook-Air:src **********$
以上です。最後まで見ていただき、ありがとうございました。
OCJP Gold SE 7(1Z0-804-JPN Java SE 7 Programmer II)を受験しました【執筆中】
はじめに
OCJP Gold SE7を受験してきました。結果は不合格でした。(チーン)
受験中よくわからなかった問題、自信を持って答えられなかった問題を記憶を頼りにまとめようと思います。
私が使用している問題集の章立てに従って、出題された問題を順に説明します。記憶だけが頼りなので問題の記述は正確には違います。あしからずご容赦ください。
また、当記事はSE8ではなく、SE7についてかかれています。SE8とはinterfaceの定義の仕方など異なるところがありますのでご注意ください。
なお、解答はEclipse4.0、jdk1.7.0_80で実際にコーディングした結果です。Oracleの公式の解答ではありません。
1章 Javaクラスの設計 2章 高度なクラス設計
Interfaceで定義できるもの
[問題]コメントを外してもコンパイルエラーにならないものを3つ選んでください。
package java.programmer.ii.no01; public interface Animal { // int value1 = 1; // 1 // final int value2 = 2; // 2 // int value3; // 3 // void func(); // 4 // static void funcStatic(); // 5 // protected void funcProtected(); // 6 }
[解答]1, 2, 4 interfaceではpublic static finalなプロパティしか定義できません。1, 2はpublic static finalと書いてありませんが、コンパイラが省略されていてもpublis static final なプロパティとしてみてくれるようなのでコンパイルエラーは発生しません。3はプロパティを初期化していないのでコンパイルエラーが発生します。4も同様にpublic abstractは省略できます。5はinterfaceには実装のないstaticメソッドを定義できないのでコンパイルエラーが発生します。6はinterfaceにはpublicメソッドしか定義できないのでコンパイルエラーが発生します。
[補足]なお、以下のように変数の修飾子はpublicのみでも、staticのみでもOKです。
package java.programmer.ii.no01; public interface Animal { // int value1 = 1; // 1 // final int value2 = 2; // 2 // int value3; // 3 public int value4 = 4; // static final 省略可能 static int value5 = 5; // public final 省略可能 // void func(); // 4 // static void funcStatic(); // 5 // protected void funcProtected(); // 6 // static void funcStaticWithImpl() {} // 実装があってもcompile error。JavaSE8からはOK }
Number, Integer, Double と instanceOf
この問題は記憶が曖昧です。
[問題]以下のコードの実行結果は次のどれですか。
package exam.no02; public class InstanceOfTest { private Number value1 = 1; private Number value2 = 0.5; private Number value3 = value1 + value2; // (a) public void func() { if (value1 instanceof Integer) { System.out.println("Integer"); } if (value2 instanceof Double) { System.out.println("Double"); } if (value3 instanceof Double) { System.out.println("Double"); } } public static void main(String[] args) { new InstanceOfTest().func(); } }
- コンパイルエラー
Integer Double Double
…
[解答]1.。(a)のところでvalue1とvalue2がunboxingされずコンパイルエラーになります。なお、以下のようにすれば2.の出力結果になります。
package exam.no02; public class InstanceOfTest { private Number value1 = 1; private Number value2 = 0.5; private Number value3 = value1.intValue() + value2.doubleValue(); public void func() { if (value1 instanceof Integer) { System.out.println("Integer"); } if (value2 instanceof Double) { System.out.println("Double"); } if (value3 instanceof Double) { System.out.println("Double"); } } public static void main(String[] args) { new InstanceOfTest().func(); } }
抽象クラスを作成するときのabstractとpublicの順番
実務では全く役に立たない知識ですが、abstrack public の順番でもOKというのは知りませんでした。
[問題]以下のうちコンパイルが成功するものはどれですか。
package exam.no03; public abstract class PublicAbstractClass {} // 1
package exam.no03; abstract public class AbstractPublicClass {} // 2
package exam.no03; public class InvalidAbstractClass1 extends Abstract {} // 3
package exam.no03; public class InvalidAbstractClass2 implements Abstract {} // 4
[解答]1, 2。3, 4が明らかにコンパイルエラーで、1が正しいことはわかったのですが、abstrackとpublicの順番が逆でもコンパイル成功することは知りませんでした。
interfaceのstatic finalの変数とスーパークラスの変数
私の場合、interfaceの変数が出力されるのか、スーパークラスの変数が出力されるのか、いつも混乱してしまいます。
[問題]次のコードの出力結果を選んでください。
package exam.no04; interface Book { String category = "book"; } class Comic implements Book { String category = "comic"; } public class HunterXHunter extends Comic { String category; public HunterXHunter() { this.category = super.category; } public static void main(String[] args) { System.out.println(new HunterXHunter().category); } }
- book
- comic
[解答]2。
[補足]なお、bookを出力するためには以下のようにします。Book.categoryとします。HunterXHunter.categoryでは取得できません。コンパイルエラーになります。
package exam.no04; interface Book { public static final String category = "book"; } class Comic implements Book { String category = "comic"; } public class HunterXHunter extends Comic { String category; public HunterXHunter() { this.category = super.category; } public static void main(String[] args) { System.out.println(new HunterXHunter().category); // comic // System.out.println(HunterXHunter.category); // compile error System.out.println(Book.category); // book } }
superclassのstaticメソッドと同じシグネチャのインスタンスメソッドをsubclassで定義した場合
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no05; class Book { static String category = "book"; static void disp() { System.out.println(category); } } class Comic extends Book { String category = "comic"; void disp() { System.out.println(category); } } public class HunterXHunter extends Comic { public static void main(String[] args) { new HunterXHunter().disp(); } }
- comic
- コンパイルエラー
[解答]2。「このインスタンス・メソッドは Book からの static メソッドをオーバーライドできません。」というメッセージとともにコンパイルエラーが発生します。
getDepth
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no06; class Lake { int depth = 5; int getDepth() { return depth; } } public class SubLake extends Lake { int depth = 10; int getDepth() { return depth; } public static void main(String[]args) { Lake lake = new SubLake(); System.out.println(lake.getDepth()); System.out.println(lake.depth); } }
- 10 5
- 10 10
[解答]1。
3章 オブジェクト指向の設計原理
Integer2つを比較→片方インクリメント→再び比較
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no07; public class IntegerTest { public static void main(String[] args) { Integer value1 = 2001; Integer value2 = value1; System.out.print(value1 == value2); System.out.print(++value1); // (a) System.out.print(value1 == value2); } }
- true2002true
- true2002false
[解答]2。value1だけがインクリメントされてもvalue1もvalue2もおなじインスタンスを参照しているはずだから両方とも2001から2002に変わると考え、私は試験時1を選択しました。しかし正しいのは2でした。これは、IntegerはImmutableなクラスであるため(a)の行でvalue1は全く別の新しいInteger(値は2002)に置き換わっているためです。(value2は2001のままです。)
singletonとEnum
この問題は、4つのコードからsingletonになっているものを2つ選択するものでした。あきらかにsingletonでない選択肢2つとよくあるsingletonの実装例と以下のEnumの実装例がありました。 Enumでsingletonの実装をできるとは知らなかったので、あげました。
- よくあるsingletonの実装
package exam.no08; public class SingletonTest { private static SingletonTest instance; private SingletonTest() { } public static synchronized SingletonTest getInstance() { if (instance == null) { return new SingletonTest(); } else { return instance; } } }
- Enumを利用したsingleton
package exam.no08; public enum Singleton { INSTANCE; }
4章 ジェネリックスとコレクション
set.add(null) → set.size()
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no09; import java.util.HashSet; import java.util.Set; public class Main { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); set.add(1); set.add(2); set.add(null); System.out.println(set.size()); } }
- 2
- 3
- コンパイルエラー
- 実行時エラー
[解答]2。私は3を選択しました。なぜ2番になるかわかりませんでしたが、以下の配列を利用したコードも出力結果は3になりました。
package exam.no09; public class Main3 { public static void main(String[] args) { Integer[] array = {1, 2, null}; System.out.println(array.length); } }
new E()
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no10; public class Printer<E> { private E e; public Printer() { e = new E(); } }
[解答] 1。new E()はできません。e = e.getClass().newInstance()もできませんでした。少し調べたところ、型引数からインスタンスを作成する方法はないようで、妥協策としてパラメーターでClassを受け取ってnewInstance()するという方法があるようです。
package exam.no10; public class Printer<E> { private E e; public Printer(Class<E> clazz) throws InstantiationException, IllegalAccessException { e = clazz.newInstance(); } void display() { System.out.println(e); } public static void main(String [] args) throws InstantiationException, IllegalAccessException { Printer<String> printer = new Printer<>(String.class); printer.display(); } }
5章 文字列処理
java.util.StringTokenizer
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no11; import java.util.StringTokenizer; public class Beatles { public static void main(String[] args) { String beatles = "John-.-Paul-.-Ringo-.-George"; StringTokenizer tokenizer = new StringTokenizer(beatles, "-.-"); while (tokenizer.hasMoreTokens()) { System.out.println(tokenizer.nextToken()); } } }
John Paul Ringo George
- コンパイルエラー
[解答]1。StringTokenizerは文字列を分割するために利用するクラスです。String.splitを使えばいいではないかと思ってどんな違いがあるのかOracleのAPIを確認したところ、互換性を保つために残っているクラスでString.splitを使うことが推奨されていました。
It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
System.out.printf() 、String.format() (%n %,.0f)
[問題]以下のコードを実行した結果がどうなるか選んでください。
package exam.no12; public class Main { public static void main(String[] args) { String city = "Tokyo"; int population = 10000; double density = 75.15; System.out.printf("Name is %1$s.%nPopulation is %2$d.%n%,.0f:density", city, population, density); } }
- 実行時エラー
- コンパイルエラー
Name is Tokyo. Population is 10000. 75:density
Name is Tokyo. Population is 10000. 75.15:density
Name is Tokyo. Population is 10000.
が出力された後に実行時エラー
[解答]3。私は受験時に5を選択しました。「%,.0f」のところで実行時エラーになると思ったからです。OracleのAPIを確認したところ、このカンマは整数部に3桁ごとにカンマを打つかどうかを表しています。たとえばdensityの値を以下のように帰ると出力結果は次に示すようになります。
package exam.no12; public class Main { public static void main(String[] args) { String city = "Tokyo"; int population = 10000; double density = 9975.15; System.out.printf("Name is %1$s.%nPopulation is %2$d.%n%3$,.0f:density", city, population, density); } }
- 出力結果
Name is Tokyo. Population is 10000. 9,975:density
java.util.Pattern, java.util.Matcher
[問題]実行結果が"Timer time time"になる[regex]にあてはまる正規表現を以下のうちどれか選択してください。
package exam.no13; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { String message = "Time time timely timer timed time"; Pattern pattern = Pattern.compile("[regex]"); Matcher matcher = pattern.matcher(message); while (matcher.find()) { System.out.print(matcher.group()); } } }
[解答]不明です。あと2つ選択肢があり、そのうちいずれかが正解だと思いますが、忘れてしまいました。
NumberFormatの取得方法
[問題]NumberFormatの取得方法として正しいものを4つ選択してください。
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
NumberFormat integerFormat = NumberFormat.getIntegerInstance();
NumberFormat numberFormat = NumberFormat.getNumberInstance();
NumberFormat parcentFormat = NumberFormat.getPercentInstance();
NumberFormat decimalFormat = new DecimalFormat();
NumberFormat decimalFormat2 = new DecimalFormat("#,###.00000");
[解答]不明。実行してみると以下のようになるので、全て正しいように思えます。ここに記述した選択肢が出題された選択肢と異なっているかもしれません。
package exam.no14; import java.text.DecimalFormat; import java.text.NumberFormat; public class Main { public static void main(String[] args) { NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(); NumberFormat integerFormat = NumberFormat.getIntegerInstance(); NumberFormat numberFormat = NumberFormat.getNumberInstance(); NumberFormat parcentFormat = NumberFormat.getPercentInstance(); NumberFormat decimalFormat = new DecimalFormat(); NumberFormat decimalFormat2 = new DecimalFormat("#,###.00000"); double value = 12345.6789; System.out.println(currencyFormat.format(value)); System.out.println(integerFormat.format(value)); System.out.println(numberFormat.format(value)); System.out.println(parcentFormat.format(value)); System.out.println(decimalFormat.format(value)); System.out.println(decimalFormat2.format(value)); } }
- 出力結果
¥12,346 12,346 12,345.679 1,234,568% 12,345.679 12,345.67890
6章 例外とアサーション
throws句でRuntimeExceptionのサブクラスを指定し、そのメソッドをオーバーライドしたメソッドのthrows句でRuntimeExceptionを指定する。
7章 Java I/Oの基礎
BufferedReader.skip
BufferedReader(fileReader(
Console.getPassword
RandomAccessFile
try-with-resource文で利用できるようにするには
try-with-resource文でクローズ後の例外を表示するには
JavaファイルI/O(NIO.2)
ファイルの移動FileChannel,Files.copy,BufferedReader
ファイルの検索(glob:*.html,htm,xml)
ファイルの監視(プラットフォームによってイベントの種類、順番は異なるか)
attr.getOwner
JDBCによるデータベースアプリケーションの作成
Connection,Statement,ResultSetはclose必要か
getConnectionのパラメーター
Statement.setMaxRows
rollback,savePoint,setAutoCommit
RowSet WebRowSet, CachedRowSet
10章 スレッド 11章 並列処理
CallableとRunnableの違い
[問題]CallableとRunnableの違いについて述べた記述のうち、正しいものを選択してください。
- CallableはExecutorService.execute()のパラメーターにできるが、Runnableはできない。
- Callableのcall()では例外をスローできるが、Runnableのrun()ではスローできない。
- Callableのcall()では戻り値を返せるが、Runnableのrun()では返せない。
[解答]3。
Thread.start2回
[問題]次のコードの実行結果として正しいものを選択してください。
package exam.no18; public class Main { public static void main(String[] args) { Thread t = new Thread(new Runnable() { public void run() { System.out.print("run "); } }); t.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t.start(); } }
run run
が出力される。run
の後に実行時エラーが発生する。
[解答]2。Threadには状態があり、一度終了したThreadは再びstartできません。なお、上のコードの実行結果は以下のようになります。
run Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:705) at exam.no18.Main.main(Main.java:17
また次のように実行中のThreadに対しstartを実行した場合も同様に実行時エラーとなります。
package exam.no18; public class Main2 { public static void main(String[] args) { Thread t = new Thread(new Runnable() { public void run() { System.out.println("run"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); t.start(); } }
runException in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:705) at exam.no18.Main2.main(Main2.java:17)
Thread.start join start
上の問題と似ていますが、joinする点で異なっています。
[問題]次のコードの実行結果として正しいものを選択してください。
package exam.no19; public class Main { public static void main(String[] args) { Thread t = new Thread(new Runnable() { public void run() { System.out.print("run "); } }); t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t.start(); } }
run run
が出力される。run
の後に実行時エラーが発生する。
[解答]2。Threadには状態があり、一度終了したThreadは再びstartできません。なお、上のコードの実行結果は以下のようになります。
run Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:705) at exam.no19.Main.main(Main.java:17)
CopyOnWriterArrayList
ローカライゼーション
Localeの取得方法(new Locale.Builder()….)
よくある問題ですが、new Locale.Builder()….という方法を始めて見たのでここで紹介しようと思います。
[問題]Localeの取得の仕方で正しいものを3つ選択してください。
1.Locale locale = new Locale("en", "US");
2.Locale locale = Locale.US;
3.Locale locale = new Locale.Builder().setLanguage("en").setRegion("US").build();
4.Locale locale = Locale.getInstance();
[解答]1, 2, 3。なお、取得したLocaleを使って、リソースを読み込むと以下のようになります。
package exam.no; import java.util.Locale; import java.util.ResourceBundle; public class Main { public static void main(String[] args) { Locale locale1 = Locale.US; Locale locale2 = new Locale("en", "US"); Locale locale3 = new Locale.Builder().setLanguage("en").setRegion("US").build(); Locale locale4 = new Locale("en"); Locale locale5 = new Locale("US"); ResourceBundle rs1 = ResourceBundle.getBundle("exam/no/greeting", locale1); System.out.println(rs1.getString("morning")); ResourceBundle rs2 = ResourceBundle.getBundle("exam/no/greeting", locale2); System.out.println(rs2.getString("morning")); ResourceBundle rs3 = ResourceBundle.getBundle("exam/no/greeting", locale3); System.out.println(rs3.getString("morning")); ResourceBundle rs4 = ResourceBundle.getBundle("exam/no/greeting", locale4); System.out.println(rs4.getString("morning")); ResourceBundle rs5 = ResourceBundle.getBundle("exam/no/greeting", locale5); System.out.println(rs5.getString("morning")); } }
- greeting.properties
morning=こんにちは evening=こんばんは
- greeting_en.properties
morning=Good morning.(without region) evening=Good evening.(without region)
- greeting_en_US.properties
morning=Good morning. evening=Good evening.
- 出力結果
Good morning. Good morning. Good morning. Good morning.(without region) こんにちは
新しいLINEスタンプを作成しました。2(審査用)
はじめに
このブログは私が作成した新スタンプの紹介のため、また、LINEスタンプの審査時に入力する「作品を確認できるURL」のために作成しました。悪しからずご容赦ください。
新スタンプ「しずくのスタンプ」
inkscapeの「カリグラフィ」で書いています。 リリースしたら、ぜひ使ってください。
さいごに
リリースしたら、また当ブログで紹介します。もし気に入ったら使ってください。
LINEクリエーターズスタンプの審査で承認されました(その2)
はじめに
2つ目のLINEクリエーターズスタンプが承認されました。 私のスタンプの審査にかかった期間とフローを記します。
審査にかかった期間
今回は12日で承認されました。 承認までの流れを以下に示します。
日付 | 時間 | ステータス |
---|---|---|
2017/02/05 | 22:30 | 申請(審査待ち) |
2017/02/14 | 15:00 | 審査中 |
2017/02/14 | 17:00 | 審査処理中 |
2017/02/16 | 21:00 | 承認 |
審査待ち→審査処理中→審査中→審査処理中→承認 となるらしいのですが、1度目の審査処理中は確認できませんでした。
前回と比べ、審査処理中の時間が長かったです。
補足
今回以下の二つを試してみました。
半透明
作品を確認するURLを設定しない
半透明
スタンプを見て貰えばわかりますが、「つかれた」のスタンプを半透明にしています。 よく透過処理ができていなくてリジェクトされたという話を聞いたので不安でしたが、無事承認されました。
作品を確認できるURLを設定しない
以前の記事で作品を確認できるURLはアクセスされていなかったので審査の期間の長短には関係がないかもしれないと書きました。実際に確認してみるため、前回と違って今回はURLを設定しなかったのですが、設定した場合審査期間は8日、していない今回は13日となりました。時期が違うので単純に日数だけで比較はできませんが、作品を確認できるURLは審査期間の長短に関係がありそうです。
さいごに
今回承認されたスタンプは、以下です。 よかったら見てください。
新しいLINEスタンプを作成しました。(審査用)
はじめに
このブログは私が作成した新スタンプの紹介のため、また、LINEスタンプの審査時に入力する「作品を確認できるURL」のために作成しました。悪しからずご容赦ください。
新スタンプ「ものくろ恐竜」
サルのスタンプに引き続き恐竜のスタンプを作成しました。 inkscapeの「カリグラフィ」で書いています。 リリースしたら、ぜひ使ってください。
さいごに
リリースしたら、また当ブログで紹介します。もし気に入ったら使ってください。
OCJP Gold SE 8 認定資格試験ポイント解説セミナーに参加しました。
はじめに
タイトルのセミナーを受けてきました。
講義していただいた内容のうち、私にとって目新しかったものをこの記事に残します。
ラムダ式と実質的final(effectively final)
実質的finalとは
Java8では、無名クラスやラムダ式で実質的にfinalな変数にアクセス可能になりました。
実質的にfinalな変数とは、final指定されていないが、final指定してもエラーにならない変数のことを言います。
具体的には以下に示すような場合実質的finalと言います。
具体例
package seminar; import java.util.Arrays; import java.util.List; public class EffectivelyFinalTest { private int value = 1; public void doSomething(int arg1, int arg2) { List<Integer> nums = Arrays.asList(1, 2, 3); // 1. 実質的final (ローカル変数) int effectivelyFinalValue = 10; nums.replaceAll(n -> n + effectivelyFinalValue); // 2. 実質的finalでない (ローカル変数) int notEffectivelyFinalValue = 20; notEffectivelyFinalValue += 10; // nums.replaceAll(n -> n + notEffectivelyFinalValue); // コンパイルエラー // 3. 実質的final (引数) nums.replaceAll(n -> n + arg1); // これはOK // 4. 実質的finalでない (引数) arg2 += 1000; // nums.replaceAll(n -> n + arg1); // コンパイルエラー // 5. インスタンス変数 value += 1; nums.replaceAll(n -> n + value); // これはOK(なぜ?) // 表示 nums.forEach(System.out::println); } public static void main(String[] args) { new EffectivelyFinalTest().doSomething(100, 1000); } }
2.をコメントアウトしないと、以下に示すメッセージが表示されます。
Local variable notEffectivelyFinalValue defined in an enclosing scope must be final or effectively final
出力結果は以下の通りです。
113 114 115
疑問点
- Java7で実質的finalな変数を無名クラス内で参照しようとするとどうなるか。
- 実質的finalな変数を無名クラス内から参照できるようにしたのは、特定の引数に対しいつでも同じ値を返すという関数のルールに反しないからだと思う。サンプルソースの5.でインスタンス変数を参照できるのはなぜか。
- 実質的finalな変数を無名クラス内から参照できるようにし、実質的finalでない変数を無名クラス内から参照できないようにするのはなぜか。
Streamの特徴
【執筆中】
- データソースのCollectionは変更されない
- 遅延評価
- 終端処理の一回性(仮)
さいごに
【執筆中】
補足
- comparingとthenComparingのちがい
【執筆中】
以上です。