22

Java の型について考察する過程で、私が理解できない奇妙な点に出くわしました。

intその修飾子を検査するとpublic、 、abstract、およびが返されますfinal。と は理解publicしていますが、プリミティブ型finalに on が存在することはわかりません。abstractこれはなぜですか?

編集:私は反省してIntegerいませんが、int

import java.lang.reflect.Modifier;

public class IntegerReflection {
    public static void main(final String[] args) {
        System.out.println(String.format("int.class == Integer.class -> %b", int.class == Integer.class));
        System.out.println(String.format("int.class modifiers: %s", Modifier.toString(int.class.getModifiers())));
        System.out.println(String.format("Integer.class modifiers: %s", Modifier.toString(Integer.class.getModifiers())));
    }
}

実行時の出力:

int.class == Integer.class -> false
int.class modifiers: public abstract final
Integer.class modifiers: public final
4

7 に答える 7

7

JLS 8.1.1.1 - 抽象クラスによると:

抽象クラスは、不完全な、または不完全と見なされるクラスです。

定義により、 のインスタンスは存在できませんint.class。この種のコードはコンパイルできません。

int a = new int();

のコンストラクタはありませんint。作成されたオブジェクトはありません。 int.class伸びませんObject。次のコード行を実行するnullと、結果として得られます。

System.out.println(int.class.getSuperclass());

したがって、 の真のインスタンスを持つことは決してできないためint.class、それは定義によるものabstractです。また、Integer APIによると、Integer.TYPEフィールド ( を保持する) は、プリミティブ型のみを表すint.classクラスです。

これは、次のコードによって証明されています。

int a = 4;
System.out.println(int.class.isInstance(a));

これは を返しますfalse

そのため、 APIint.classで述べられているように、表現目的でシステムで使用される可能性があります。Integer型もあってvoid.class型がないnull.classということは、これは主にリフレクションで使われていると思います。ただし、これは単なる推測です。


誰かが興味を持っている場合int.class、リフレクション パッケージが認識するものは本質的に何も含まれておらず、おそらく単なるダミー クラスです。次のコードを実行すると、コンストラクタ、フィールド、メソッドがないことがわかります。

Method[] intMethods = int.class.getMethods();

if(intMethods.length == 0) {
    System.out.println("No methods.");
}
else {
    for(Method method : intMethods) {
        System.out.println(method.getName());
    }
}

Constructor[] intConstructors = int.class.getConstructors();

if(intConstructors.length == 0) {
    System.out.println("No constructors.");
}
else {
    for(Constructor constructor: intConstructors) {
        System.out.println(constructor.getName());
    }
}

Field[] intFields = int.class.getFields();

if(intFields.length == 0) {
    System.out.println("No fields.");
}
else {
    for(Field field: intFields) {
        System.out.println(field.getName());
    }
}
于 2012-11-01T16:08:53.877 に答える
5

あなたが実行する場合

System.out.println(Modifier.toString(int.class.getModifiers()));

あなたが得る

public abstract final

おそらく、それをサブクラス化できないためです-つまり、最終的であり、インスタンス化できません-つまり、抽象的です。

オラクルの抽象メソッドとクラスから

抽象クラスはインスタンス化できませんが、サブクラス化できます。

事実は、それがサブクラスになることができないという最終的な意味でもあります。

于 2012-11-01T15:51:42.003 に答える
3

JVM仕様から:

抽象クラスは、不完全な、または不完全と見なされるクラスです。抽象クラスのみが抽象メソッド、つまり、宣言されているがまだ実装されていないメソッドを持つことができます。

クラスの定義が完了し、サブクラスが必要ないか必要でない場合は、そのクラスを final として宣言できます。最終クラスにはサブクラスがないため、最終クラスのメソッドをサブクラスでオーバーライドすることはできません。クラスを final と abstract の両方にすることはできません。そのようなクラスの実装は決して完了することができないからです。

仕様によれば、クラスを抽象と最終の両方にすることはできません。ただし、JVM はプリミティブ型をクラスとして扱わないようです。プリミティブ型はクラスではなく、JVM によって (を使用して) 言語ランタイムに提供されるため、技術的には正しいClass getPrimitiveClass(const char *name)です。

だからint、そして他のすべてのプリミティブ型、

> a. Should be accessible from within the language: Make it `public` 
> b. Should not be extensible                     : Make it `final` 
> c. Should not be instantiated with `new`        : Make it `abstract`.

プリミティブ型が存在する理由についての JVM 仕様からの私の理論はabstract、それらが不完全であると見なされているためです。

于 2012-11-01T19:22:39.647 に答える
-2

抽象クラスから継承されたクラスに反映し、そのインスタンスの基本クラスを掘り下げようとした場合、抽象クラスで抽象として定義されたプロパティには値がありませんが、それはクラス定義の一部です。

例を次に示します。

public class absBase{

    private string name;
    private int ID;

    public abstract int GetID();
}

public class concreteClass:absBase{
    @Override
    public int GetID(){
        return ID + 1;
    }
}

したがって、absBase を反映していて GetID を見た場合、concreteClass.GetID() を見た場合は定義上抽象的である必要がありますが、パブリックになります。それが役立つことを願っています。

于 2012-11-01T15:51:02.290 に答える