Java
#3
TIOBE#4
PYPL#2
GitHub#8
RedMonk#3
IEEESpectrum#2
JetBrains#5
プログラミング言語
Java
概要
Javaは「一度書けばどこでも動く」をコンセプトとするオブジェクト指向プログラミング言語です。
詳細
Javaは1995年にSun Microsystems(現Oracle)によって開発されたオブジェクト指向プログラミング言語です。「Write Once, Run Anywhere」(WORA)の理念のもと、Java仮想マシン(JVM)上で動作することで、プラットフォームに依存しないアプリケーション開発を可能にしています。強い型付け、自動メモリ管理(ガベージコレクション)、豊富な標準ライブラリを特徴とし、エンタープライズ開発、Webアプリケーション、Androidアプリ開発、ビッグデータ処理など幅広い分野で使用されています。Oracle、IBM、Google、LinkedInなどの大手企業が重要なシステムでJavaを採用しており、安定性と信頼性の高さで知られています。
書き方の例
Hello World
// 基本的なHello World
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
// 変数を使った出力
String message = "こんにちは、Java!";
System.out.println(message);
// 文字列の連結
String name = "太郎";
int age = 25;
System.out.println("私の名前は" + name + "で、" + age + "歳です。");
// printf形式の出力
System.out.printf("私の名前は%sで、%d歳です。%n", name, age);
}
}
// パッケージを使用した例
package com.example.hello;
public class HelloJava {
public static void main(String[] args) {
System.out.println("Hello from Java package!");
}
}
変数とデータ型
public class Variables {
public static void main(String[] args) {
// 基本データ型(プリミティブ型)
int number = 42;
long bigNumber = 1234567890L;
float price = 99.99f;
double pi = 3.14159;
char initial = 'J';
boolean isActive = true;
byte smallNumber = 100;
short mediumNumber = 30000;
// 参照型
String name = "田中太郎";
String nullString = null;
// 配列
int[] numbers = {1, 2, 3, 4, 5};
String[] names = new String[3];
names[0] = "田中";
names[1] = "山田";
names[2] = "佐藤";
// 定数(final)
final double TAX_RATE = 0.1;
final String COMPANY_NAME = "ABC株式会社";
// 型推論(Java 10以降)
var message = "これは文字列です"; // String型として推論
var count = 10; // int型として推論
var items = new String[]{"アイテム1", "アイテム2"}; // String[]型として推論
// 出力例
System.out.println("数値: " + number);
System.out.println("大きな数値: " + bigNumber);
System.out.println("価格: " + price);
System.out.println("円周率: " + pi);
System.out.println("初期文字: " + initial);
System.out.println("アクティブ: " + isActive);
System.out.println("名前: " + name);
// 配列の出力
System.out.println("数値配列: " + java.util.Arrays.toString(numbers));
System.out.println("名前配列: " + java.util.Arrays.toString(names));
// null チェック
if (nullString == null) {
System.out.println("nullStringはnullです");
}
}
}
メソッド
public class Methods {
// 基本的なメソッド
public static int add(int a, int b) {
return a + b;
}
// メソッドオーバーロード
public static double add(double a, double b) {
return a + b;
}
public static String add(String a, String b) {
return a + b;
}
// 可変長引数
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
// 戻り値なしのメソッド
public static void printMessage(String message) {
System.out.println("メッセージ: " + message);
}
// 配列を引数とするメソッド
public static void printArray(String[] array) {
for (String item : array) {
System.out.println("- " + item);
}
}
// 再帰メソッド
public static int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
// メソッドの呼び出し
System.out.println("5 + 3 = " + add(5, 3));
System.out.println("2.5 + 3.7 = " + add(2.5, 3.7));
System.out.println("Hello + World = " + add("Hello", "World"));
// 可変長引数
System.out.println("合計: " + sum(1, 2, 3, 4, 5));
System.out.println("合計: " + sum(10, 20));
// 戻り値なしのメソッド
printMessage("こんにちは、Java!");
// 配列を渡す
String[] fruits = {"りんご", "バナナ", "オレンジ"};
printArray(fruits);
// 再帰メソッド
System.out.println("5の階乗: " + factorial(5));
}
}
クラスとオブジェクト
// 基本的なクラス
class Person {
// フィールド(プライベート)
private String name;
private int age;
private String email;
// コンストラクタ
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// オーバーロードされたコンストラクタ
public Person(String name, int age, String email) {
this(name, age); // 他のコンストラクタを呼び出し
this.email = email;
}
// ゲッター
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
// セッター
public void setAge(int age) {
if (age >= 0) {
this.age = age;
}
}
public void setEmail(String email) {
this.email = email;
}
// メソッド
public void introduce() {
System.out.println("私の名前は" + name + "で、" + age + "歳です。");
if (email != null) {
System.out.println("メールアドレス: " + email);
}
}
// static メソッド
public static Person createDefaultPerson() {
return new Person("名前なし", 0);
}
// toString メソッドのオーバーライド
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", email='" + email + "'}";
}
}
// 抽象クラス
abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public abstract void makeSound();
public void sleep() {
System.out.println(name + "は眠っています。");
}
}
// 継承
class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println(name + "(" + breed + ")がワンワンと鳴いています。");
}
public void fetch() {
System.out.println(name + "がボールを取ってきました。");
}
}
// インターフェース
interface Drawable {
void draw();
// デフォルトメソッド(Java 8以降)
default void info() {
System.out.println("これは描画可能なオブジェクトです。");
}
// static メソッド(Java 8以降)
static void showVersion() {
System.out.println("Drawable interface v1.0");
}
}
// インターフェースの実装
class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("半径 " + radius + " の円を描画します。");
}
public double getArea() {
return Math.PI * radius * radius;
}
}
public class ClassExample {
public static void main(String[] args) {
// オブジェクトの作成
Person person1 = new Person("田中太郎", 25);
Person person2 = new Person("山田花子", 30, "[email protected]");
// メソッドの呼び出し
person1.introduce();
person2.introduce();
// セッターの使用
person1.setEmail("[email protected]");
person1.introduce();
// toString の使用
System.out.println(person1);
// static メソッドの呼び出し
Person defaultPerson = Person.createDefaultPerson();
defaultPerson.introduce();
// 継承の例
Dog dog = new Dog("ポチ", "柴犬");
dog.makeSound();
dog.fetch();
dog.sleep();
// インターフェースの例
Circle circle = new Circle(5.0);
circle.draw();
circle.info();
System.out.println("円の面積: " + circle.getArea());
// static メソッドの呼び出し
Drawable.showVersion();
}
}
コレクションフレームワーク
import java.util.*;
import java.util.stream.Collectors;
public class Collections {
public static void main(String[] args) {
// ArrayList
List<String> fruits = new ArrayList<>();
fruits.add("りんご");
fruits.add("バナナ");
fruits.add("オレンジ");
fruits.add("りんご"); // 重複可能
System.out.println("フルーツリスト: " + fruits);
System.out.println("最初の要素: " + fruits.get(0));
System.out.println("サイズ: " + fruits.size());
// 拡張for文(for-each)
System.out.println("各フルーツ:");
for (String fruit : fruits) {
System.out.println("- " + fruit);
}
// HashSet(重複なし)
Set<String> uniqueFruits = new HashSet<>(fruits);
System.out.println("ユニークなフルーツ: " + uniqueFruits);
// HashMap
Map<String, Integer> fruitPrices = new HashMap<>();
fruitPrices.put("りんご", 100);
fruitPrices.put("バナナ", 80);
fruitPrices.put("オレンジ", 120);
System.out.println("フルーツの価格:");
for (Map.Entry<String, Integer> entry : fruitPrices.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue() + "円");
}
// Stream API(Java 8以降)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// フィルタリング
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("偶数: " + evenNumbers);
// マッピング
List<Integer> doubled = numbers.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println("倍数: " + doubled);
// 合計
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("合計: " + sum);
// 条件に一致する要素の検索
Optional<String> expensiveFruit = fruitPrices.entrySet().stream()
.filter(entry -> entry.getValue() > 100)
.map(Map.Entry::getKey)
.findFirst();
if (expensiveFruit.isPresent()) {
System.out.println("高価なフルーツ: " + expensiveFruit.get());
}
// グループ化
List<String> words = Arrays.asList("apple", "banana", "apricot", "cherry", "avocado");
Map<Character, List<String>> groupedWords = words.stream()
.collect(Collectors.groupingBy(word -> word.charAt(0)));
System.out.println("最初の文字でグループ化: " + groupedWords);
}
}
例外処理
// カスタム例外クラス
class ValidationException extends Exception {
public ValidationException(String message) {
super(message);
}
}
class AgeOutOfRangeException extends RuntimeException {
public AgeOutOfRangeException(String message) {
super(message);
}
}
public class ExceptionHandling {
// チェック例外をスローするメソッド
public static void validateEmail(String email) throws ValidationException {
if (email == null || !email.contains("@")) {
throw new ValidationException("無効なメールアドレスです: " + email);
}
}
// 非チェック例外をスローするメソッド
public static void validateAge(int age) {
if (age < 0 || age > 150) {
throw new AgeOutOfRangeException("年齢は0から150の間である必要があります: " + age);
}
}
public static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("ゼロで除算はできません");
}
return a / b;
}
public static void main(String[] args) {
// try-catch文
try {
int result = divide(10, 2);
System.out.println("10 ÷ 2 = " + result);
} catch (ArithmeticException e) {
System.out.println("算術エラー: " + e.getMessage());
}
// 複数の例外をキャッチ
try {
validateEmail("invalid-email");
} catch (ValidationException e) {
System.out.println("検証エラー: " + e.getMessage());
}
// 非チェック例外のキャッチ
try {
validateAge(-5);
} catch (AgeOutOfRangeException e) {
System.out.println("年齢エラー: " + e.getMessage());
}
// 複数の例外タイプを一度にキャッチ(Java 7以降)
try {
int[] array = {1, 2, 3};
System.out.println(array[5]); // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
System.out.println("配列または null エラー: " + e.getMessage());
}
// finally句
try {
System.out.println("処理を実行中...");
// 何らかの処理
} catch (Exception e) {
System.out.println("エラーが発生しました: " + e.getMessage());
} finally {
System.out.println("cleanup処理(必ず実行される)");
}
// try-with-resources(Java 7以降)
try (Scanner scanner = new Scanner(System.in)) {
// リソースが自動的にクローズされる
System.out.println("Scanner が自動的にクローズされます");
} catch (Exception e) {
System.out.println("Scanner エラー: " + e.getMessage());
}
// throw文を使った例外の再スロー
try {
handleException();
} catch (Exception e) {
System.out.println("キャッチされた例外: " + e.getMessage());
}
}
private static void handleException() throws Exception {
try {
divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("内部でキャッチ: " + e.getMessage());
throw new Exception("処理に失敗しました", e); // 原因となる例外を保持
}
}
}
ジェネリクス
import java.util.*;
// ジェネリッククラス
class Box<T> {
private T content;
public void set(T content) {
this.content = content;
}
public T get() {
return content;
}
@Override
public String toString() {
return "Box{content=" + content + "}";
}
}
// 複数の型パラメータ
class Pair<T, U> {
private T first;
private U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public U getSecond() { return second; }
@Override
public String toString() {
return "Pair{first=" + first + ", second=" + second + "}";
}
}
// 境界付き型パラメータ
class NumberBox<T extends Number> {
private T number;
public NumberBox(T number) {
this.number = number;
}
public double getDoubleValue() {
return number.doubleValue();
}
}
public class Generics {
// ジェネリックメソッド
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
// 複数の型パラメータを持つジェネリックメソッド
public static <T, U> void printPair(T first, U second) {
System.out.println("ペア: " + first + " と " + second);
}
// ワイルドカード
public static void printList(List<?> list) {
for (Object item : list) {
System.out.println("- " + item);
}
}
// 上限境界ワイルドカード
public static double sumOfNumbers(List<? extends Number> numbers) {
double sum = 0.0;
for (Number num : numbers) {
sum += num.doubleValue();
}
return sum;
}
// 下限境界ワイルドカード
public static void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
list.add(3);
}
public static void main(String[] args) {
// ジェネリッククラスの使用
Box<String> stringBox = new Box<>();
stringBox.set("Hello, Generics!");
System.out.println("文字列ボックス: " + stringBox.get());
Box<Integer> numberBox = new Box<>();
numberBox.set(42);
System.out.println("数値ボックス: " + numberBox.get());
// 複数の型パラメータ
Pair<String, Integer> nameAge = new Pair<>("田中", 25);
System.out.println("名前と年齢: " + nameAge);
// 境界付き型パラメータ
NumberBox<Integer> intBox = new NumberBox<>(100);
NumberBox<Double> doubleBox = new NumberBox<>(3.14);
System.out.println("整数ボックス: " + intBox.getDoubleValue());
System.out.println("実数ボックス: " + doubleBox.getDoubleValue());
// ジェネリックメソッド
String[] words = {"Hello", "World", "Java"};
System.out.println("交換前: " + Arrays.toString(words));
swap(words, 0, 2);
System.out.println("交換後: " + Arrays.toString(words));
// 複数の型パラメータ
printPair("名前", "田中");
printPair(100, 200);
// ワイルドカード
List<String> stringList = Arrays.asList("りんご", "バナナ", "オレンジ");
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("文字列リスト:");
printList(stringList);
System.out.println("整数リスト:");
printList(intList);
// 上限境界ワイルドカード
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
System.out.println("整数の合計: " + sumOfNumbers(integers));
System.out.println("実数の合計: " + sumOfNumbers(doubles));
// 下限境界ワイルドカード
List<Number> numbers = new ArrayList<>();
addNumbers(numbers);
System.out.println("追加された数値: " + numbers);
}
}
バージョン
バージョン | リリース日 | 主な新機能 |
---|---|---|
Java 21 (LTS) | 2023-09 | Virtual Threads, Pattern Matching, Record Patterns |
Java 17 (LTS) | 2021-09 | Sealed Classes, Pattern Matching for switch |
Java 11 (LTS) | 2018-09 | Local-Variable Syntax for Lambda, HTTP Client API |
Java 8 (LTS) | 2014-03 | Lambda Expressions, Stream API, Optional |
Java 7 | 2011-07 | Try-with-resources, Diamond operator |
Java 6 | 2006-12 | Scripting API, Compiler API |
Java 5 | 2004-09 | Generics, Annotations, Autoboxing |
参考ページ
公式ドキュメント
- Java公式サイト - 公式サイト
- Oracle Java Documentation - Oracle公式ドキュメント
- OpenJDK - オープンソース実装
学習リソース
- Oracle Java Tutorials - Oracle公式チュートリアル
- Java Code Geeks - Java開発者向けリソース
- Baeldung - Java・Spring総合学習サイト
開発ツール
- IntelliJ IDEA - 人気のJava IDE
- Eclipse - オープンソースJava IDE
- Maven - プロジェクト管理・ビルドツール
- Gradle - モダンなビルドツール