import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
class Main {
public static String myFunc(Function<String, String> callback) {
return callback.apply("hi");
}
public static void main(String args[]) {
// コールバック関数
System.out.println(myFunc(s -> s + "!")); //=> hi!
// Scala のようなコレクション操作
List<String> list = Arrays.asList("aaa", "bbb");
list.forEach(s -> System.out.println(s));
for(String s: list) { // Java 7 までのよくある書き方
System.out.println(s);
}
// 変数に代入
Function<String, String> func = (String s) -> {
return s + "!";
};
Function<String, String> func2 = (String s) -> s + "!"; // 一行記法
Function<String, String> func3 = s -> s + "!"; // 型の省略
System.out.println(func.apply("hi")); //=> hi!
System.out.println(func2.apply("hi")); //=> hi!
System.out.println(func3.apply("hi")); //=> hi!
}
}
Java 8 から Interface が実装をもてるようになりました。Scala トレイトのようなものです。
MyInterface.java
public interface MyInterface {
default public String func() {
return "MyInterface.func";
}
}
MyClass.java
public class MyClass implements MyInterface {
// オーバーライドする場合
// public String func() {
// return "hello, " + MyInterface.super.func();
// }
}
Main.java
class Main {
public static void main(String args[]) {
MyInterface obj = new MyClass();
System.out.println(obj.func());
}
}
実行例
$ javac *.java && java Main
MyInterface.func
通常 import
は、あるパッケージのクラスを指定します。import static
とすることで、あるパッケージのクラスの静的メンバを指定できます。
import static java.lang.Math.PI;
import static java.lang.Math.cos;
class Main {
public static void main(String args[]) {
System.out.println(cos(PI)); //=> -1.0
}
}
MyClass.java
public class MyClass {
private String str = "abc";
private class MyInnerClass {
private String func() {
return str;
}
}
public String func() {
MyInnerClass obj = new MyInnerClass();
return obj.func();
}
}
Main.java
class Main {
public static void main(String args[]) {
MyClass obj = new MyClass();
System.out.println(obj.func());
}
}
実行例
$ javac *.java && java Main
abc
Java の例外クラスは java.lang.Throwable
を継承する以下の三つのクラスのいずれかを継承しています。
java.lang.Error
(JVM の実行が継続できない致命的なエラー; try-catch-finally で扱うものではありません)java.lang.Exception
(検査例外; コンパイル時に try-catch-finally の実装が強制されます)java.lang.RuntimeException
(実行時例外; コンパイル時に try-catch-finally の実装が強制されません。java.lang.Exception
を継承しています)Error
, Exception
, RuntimeException
それぞれの具体例は、以下の Javadoc で確認できます。例えば NullPointerException
は RuntimeException
です。
実行時例外の例
class Main {
public static void myFunc() throws ArithmeticException, NullPointerException { // いずれも実行時例外
throw new NullPointerException("ぬるぽ");
}
public static void main(String args[]) {
myFunc(); // 実行時例外は try-catch で囲まなくてもコンパイルは通ります。
}
}
例外情報の表示
class Main {
public static void main(String args[]) {
try {
throw new NullPointerException("ぬるぽ");
}
catch (ArithmeticException | NullPointerException e) {
System.out.println(e.getMessage()); //=> ぬるぽ
e.printStackTrace(); //=> java.lang.NullPointerException: ぬるぽ...
}
}
}
Java 7 から利用できる、リソースを自動でクローズする構文 (try-with-resources)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;
class Main {
public static void main(String args[]) {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Main.java"), "UTF-8"));
BufferedReader reader2 = new BufferedReader(new InputStreamReader(new FileInputStream("Main.java"), "UTF-8"))) {
String line = null;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
import java.util.Map;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Main {
public static void main(String args[]) {
try {
// コマンド指定
ProcessBuilder processBuilder = new ProcessBuilder("ls", "-l");
// 環境変数の操作
Map<String, String> environment = processBuilder.environment();
System.out.println(environment.get("PATH"));
environment.put("DUMMY", "aaa");
// プロセスの動作ディレクトリを指定して非同期実行
Process process = processBuilder.directory(new File("/")).start();
// 標準 (エラー) 出力を取得
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
// 非同期実行したプロセスが終了するのを待つ
process.waitFor();
// process.destroy(); // 強制終了したい場合
// 終了ステータス
System.out.println(process.exitValue()); //=> 0 (正常)
}
catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.Arrays;
import java.util.List;
import java.util.Map;
class Main {
public static void main(String args[]) {
// JVM システムプロパティ (Java 8 で表示する例)
System.setProperty("my.prop1", "123"); // `java -Dmy.prop1=123 Main` と同じ効果
List<String> list = Arrays.asList("my.prop1", //=> 123
"file.encoding", //=> UTF-8
"file.separator", //=> /
"path.separator", //=> :
"java.version", //=> 1.8.0_60
"java.vm.name", //=> Java HotSpot(TM) 64-Bit Server VM
"java.home", //=> /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre
"java.library.path", //=> /Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
"os.name", //=> Mac OS X
"os.version", //=> 10.10.5
"os.arch", //=> x86_64
"user.dir"); //=> /path/to/current/dir
list.forEach(s -> System.out.println(System.getProperty(s)));
// JVM プロセスの環境変数 (Java 8 で表示する例)
Map<String, String> map = System.getenv();
map.forEach((key, value) -> System.out.println(key + "=" + value));
System.out.println(System.getenv("PATH")); //=> /usr/local/bin:/usr/bin:/bin
}
}
クラスの構造を実行中に読み取ることができます。
Main.java
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Main {
public static String toString(Object obj) {
StringBuilder sb = new StringBuilder();
Class clazz = obj.getClass(); // Class インスタンス
sb.append(clazz.getName());
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();
for(Field field : fields) {
sb.append("," + field.getName());
}
for(Method method : methods) {
sb.append("," + method.getName());
}
return sb.toString();
}
public static void main(String args[]) {
MyClass obj = new MyClass();
System.out.println(Main.toString(obj));
}
}
MyClass.java
public class MyClass {
public int iPublic;
private int iPrivate;
public void methodPublic(){}
private void methodPrivate(){}
}
実行例
$ javac *.java && java Main
MyClass,iPublic,iPrivate,methodPublic,methodPrivate
Java SE 5 から導入された、C++ のテンプレートのような機能です。こちらのページでまとめた Java コレクションのリストで List<Integer> list
といった記述を行うことで、リストに格納される要素の型を明記できます。リストクラスのように、型を明記せずにジェネリックな状態で汎用的に定義することで、特定の型に依存しないクラスを定義できます。
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass<String> objStr = new MyClass<String>("string");
System.out.println(objStr.get());
}
}
MyClass.java
package myproject;
public class MyClass<T> {
T obj;
public MyClass(T obj) {
this.obj = obj;
}
public T get() {
return obj;
}
}
実行例
string