Java Language
非アクセス修飾子
サーチ…
前書き
非アクセス修飾子は、変数やメソッドのアクセシビリティを変更するものではありませんが、 特別なプロパティを提供します 。
最後の
Javaのfinal
は変数、メソッド、クラスを参照できます。 3つの簡単なルールがあります:
- 最終変数を再割り当てすることはできません
- 最終的な方法をオーバーライドすることはできません
- 最終クラスは拡張できません
用途
良いプログラミング実践
いくつかの開発者は可能なときに変数finalをマークすることをお勧めします。変えてはいけない変数がある場合は、それを最終的にマークする必要があります。
メソッドのパラメータの場合は、 final
キーワードの重要な使用。メソッドが入力パラメータを変更しないことを強調したい場合は、プロパティをfinalとしてマークします。
public int sumup(final List<Integer> ints);
これは、 sumup
メソッドがints
を変更しないことを強調していints
。
インナークラスアクセス
あなたの匿名の内部クラスが変数にアクセスしたい場合は、変数にfinal
とマークする必要があります
public IPrintName printName(){
String name;
return new IPrintName(){
@Override
public void printName(){
System.out.println(name);
}
};
}
このクラスはコンパイルされず、変数name
はfinalではありません。
効果的な最終変数は例外です。これらはローカル変数であり、一度だけ書き込まれるため、最終的に作成することができます。効果的な最終変数は匿名クラスからもアクセスできます。
final static
変数
以下のコードは、ときに完全に合法であってもfinal
変数foo
ないstatic
の場合、 static
それがコンパイルされません。
class TestFinal {
private final static List foo;
public Test() {
foo = new ArrayList();
}
}
理由は、もう一度やり直しましょう。 最終的な変数は再割り当てできません 。 foo
は静的なので、 TestFinal
クラスのすべてのインスタンスで共有されます。 TestFinal
クラスの新しいインスタンスが作成されると、そのコンストラクターが呼び出されるため、コンパイラーが許可しないfooが再割り当てされます。この場合、変数foo
を初期化する正しい方法は、次のいずれかです。
class TestFinal {
private static final List foo = new ArrayList();
//..
}
または静的初期化子を使用して
class TestFinal {
private static final List foo;
static {
foo = new ArrayList();
}
//..
}
final
的なメソッドは、基底クラスが、派生クラスがそれを変更することを想定していない重要な機能を実装する場合に便利です。仮想テーブルのコンセプトが存在しないため、非最終メソッドよりも高速です。
Javaのすべてのラッパークラスは、 Integer
、 Long
などのように最終的です。これらのクラスのクリエイターは、Integerを自分のクラスに拡張し、Integerクラスの基本的な動作を変更することはできません。クラスを不変にするための要件の1つは、サブクラスがメソッドをオーバーライドできないことです。これを行う最も簡単な方法は、クラスをfinal
として宣言することです。
揮発性の
volatile
修飾子は、マルチスレッドプログラミングで使用されます。フィールドをvolatile
と宣言すると、フィールドをローカルにキャッシュされていない最新の値を読み取る必要があることをスレッドに知らせるシグナルとなります。さらに、 volatile
読み取りと書き込みはアトミック(非volatile
long
またはdouble
アクセスはアトミックではない)であることが保証されているため、複数のスレッド間で一定の読み取り/書き込みエラーが発生しません。
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run(){ // run is called in one thread
active = true;
while (active){
// some code here
}
}
public void stop(){ // stop() is called from another thread
active = false;
}
}
静的
static
キーワードは、クラス、メソッド、またはフィールドで使用され、クラスのインスタンスとは無関係に動作します。
- 静的フィールドは、クラスのすべてのインスタンスに共通です。彼らはそれらにアクセスするためのインスタンスを必要としません。
- 静的メソッドは、そのクラスのインスタンスなしで実行できますが、そのクラスの静的フィールドにのみアクセスできます。
- 静的クラスは他のクラスの中で宣言することができます。インスタンス化するクラスのインスタンスは必要ありません。
public class TestStatic
{
static int staticVariable;
static {
// This block of code is run when the class first loads
staticVariable = 11;
}
int nonStaticVariable = 5;
static void doSomething() {
// We can access static variables from static methods
staticVariable = 10;
}
void add() {
// We can access both static and non-static variables from non-static methods
nonStaticVariable += staticVariable;
}
static class StaticInnerClass {
int number;
public StaticInnerClass(int _number) {
number = _number;
}
void doSomething() {
// We can access number and staticVariable, but not nonStaticVariable
number += staticVariable;
}
int getNumber() {
return number;
}
}
}
// Static fields and methods
TestStatic object1 = new TestStatic();
System.out.println(object1.staticVariable); // 11
System.out.println(TestStatic.staticVariable); // 11
TestStatic.doSomething();
TestStatic object2 = new TestStatic();
System.out.println(object1.staticVariable); // 10
System.out.println(object2.staticVariable); // 10
System.out.println(TestStatic.staticVariable); // 10
object1.add();
System.out.println(object1.nonStaticVariable); // 15
System.out.println(object2.nonStaticVariable); // 10
// Static inner classes
StaticInnerClass object3 = new TestStatic.StaticInnerClass(100);
StaticInnerClass object4 = new TestStatic.StaticInnerClass(200);
System.out.println(object3.getNumber()); // 100
System.out.println(object4.getNumber()); // 200
object3.doSomething();
System.out.println(object3.getNumber()); // 110
System.out.println(object4.getNumber()); // 200
抽象
抽象化は、実装の詳細を隠し、機能だけをユーザーに示すプロセスです。抽象クラスはインスタンス化できません。抽象クラスとして宣言されたクラスは、クラスの拡張のみを目的としています。
abstract class Car
{
abstract void tagLine();
}
class Honda extends Car
{
void tagLine()
{
System.out.println("Start Something Special");
}
}
class Toyota extends Car
{
void tagLine()
{
System.out.println("Drive Your Dreams");
}
}
同期された
同期化修飾子は、特定のメソッドまたは複数のスレッドによるブロックのアクセスを制御するために使用されます。 synchronizedとして宣言されているメソッドまたはブロックには、1つのスレッドだけが入ることができます。 synchronizedキーワードはオブジェクトの本来のロックに作用し、同期メソッドの場合には現在のオブジェクトロックを持ち、静的メソッドはクラスオブジェクトを使用します。同期ブロックを実行しようとするスレッドは、最初にオブジェクトロックを取得する必要があります。
class Shared
{
int i;
synchronized void SharedMethod()
{
Thread t = Thread.currentThread();
for(int i = 0; i <= 1000; i++)
{
System.out.println(t.getName()+" : "+i);
}
}
void SharedMethod2()
{
synchronized (this)
{
System.out.println("Thais access to currect object is synchronize "+this);
}
}
}
public class ThreadsInJava
{
public static void main(String[] args)
{
final Shared s1 = new Shared();
Thread t1 = new Thread("Thread - 1")
{
@Override
public void run()
{
s1.SharedMethod();
}
};
Thread t2 = new Thread("Thread - 2")
{
@Override
public void run()
{
s1.SharedMethod();
}
};
t1.start();
t2.start();
}
}
一時的な
一時変数として宣言された変数は、オブジェクトの直列化中にシリアル化されません。
public transient int limit = 55; // will not persist
public int b; // will persist
strictfp
strictfp修飾子は、浮動小数点計算に使用されます。この変更子は、浮動小数点変数を複数のプラットフォームでより一貫性のあるものにし、浮動小数点計算がIEEE 754標準に従って行われ、32ビットおよび64ビットアーキテクチャの両方で計算(丸め誤差)、オーバーフローおよびアンダーフローのエラーを回避します。これは、抽象メソッド、変数、またはコンストラクタには適用できません。
// strictfp keyword can be applied on methods, classes and interfaces.
strictfp class A{}
strictfp interface M{}
class A{
strictfp void m(){}
}