什么是MyClass.class?

时间:2009-06-29 12:34:25

标签: java

以下是MainClass.java中列出的代码。

public class MainClass {

    public static void main(String[] args) {

        System.out.println("main started...");

        Class c = MyClass.class ;
                        //this class variable seems to be public static.
                        //But, as it is clearly visible in the MyClass,
                        //no reference variable is declared.
                        //My problem is that from where this class variable
                        //came from.
                        //i also check out the Object.java file, but it also don't
                        //have any public static class variable of Class class
                        //like there is
                        //out (instance of PrintStream class) in System class.
                        //Hope all u mindoverflow guys help me to sort out
                        //this probz.

        try {
            Class.forName( c.getName() ) ;

            System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader());

            System.out.println("classloader of MyClass : " + String.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("main ended...");
    }
}

class MyClass{
    static{
        System.out.println("static block of MyClass class.");
    }
}
thnx coobird ... 我觉得这篇文章很有用。 :)

但是,关于文学,我的知识仅限于:

int i = 5 ;  //here 5 is an integer literal

float f = 5.6f ;  //here 5.6f is a float literal

唯一的非原始文字,我知道是

String str = "java" ;   //"java" is a String litereal

和类文字,你和Jon Skeet非常清楚地告诉我。

在java ???中找到更多的文字


...商定 因此,根据讨论,总文字被归类为: -

  • 原始文字
  • 字符串文字
  • class literal

还有更多的文字(使列表更长一点:)


当我使用decomipler,两个Class反编译MainClass.class时 发现自动添加类型静态变量(可能是coz,我已经使用过类文字2次),但是从未发现它被使用过 在代码中。此外,两个类文字都直接替换为我在java文件中使用它们的类文件。

我的代码: -

public class MainClass {

    public static void main(String[] args) {

        System.out.println("main started...");

        Class c = MyClass.class ;

        try {
            Class.forName( c.getName() ) ;

            System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader());

            System.out.println("classloader of MyClass : " + String.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("main ended...");
    }
}

反编译器生成的代码: -

import java.io.PrintStream;

public class MainClass
{

    public MainClass()
    {
    }

    public static void main(String args[])
    {
        System.out.println("main started...");
        Class c = MyClass;
        try
        {
            Class.forName(c.getName());
            System.out.println((new StringBuilder("classloader of MyClass : ")).append(MyClass.getClassLoader()).toString());
            System.out.println((new StringBuilder("classloader of MyClass : ")).append(java/lang/String.getClassLoader()).toString());
        }
        catch(ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        System.out.println("main ended...");
    }

    static Class class$0;
    static Class class$1;
}

4 个答案:

答案 0 :(得分:9)

这是“类文字” - 获取特定类型的Class<T>的简单方法。

有关详细信息,请参阅Java语言规范的section 15.8.2

请注意,它不是该类的“字段”,它是一种特殊的语法糖。

由于类型擦除,您可能会遇到有关泛型的有趣限制。 Guice中引入的TypeLiteral提供了更多信息和解决方法。

在实现方面,它取决于您要定位的字节码版本。如果使用-target 1.4(或以下),则会在类型初始化期间调用的静态方法中将Class.forName()调用插入到代码中。如果使用-target 1.5(或更高版本),常量池将获得“类”条目。我不知道如何处理这个细节。

答案 1 :(得分:3)

编写MyClass.class会提供Class<MyClass>类型的对象。

因此,在上面的代码中,如果要正确使用泛型,那么应该说:

Class<MyClass> c = MyClass.class;

Class<?> c = MyClass.class;

class关键字将提供对该类进行建模的Class对象。

正如Jon Skeet所提到的,Section 15.8.2: Class LiteralsThe Java Language Specification说了关于班级文字的以下内容:

  

类文字是一个表达式   由一个类的名称组成,   接口,数组或基元类型,   或伪型void,后跟a   ''和令牌class。的类型   class literal,C.Class,其中C   类,接口或数组的名称   类型,是Class<C>

     

类文字根据定义评估指定类型(或void)的Class对象   通过当前实例的类的定义类加载器。

答案 2 :(得分:0)

要添加其他人已经说过的内容,“MyClass.class”在语义上与:

相同
Class.forName("MyClass", false, classloader);

其中“classloader”是调用类的ClassLoader实例。

主要区别在于异常处理 - 上面的代码片段抛出了ClassNotFoundException,但我不相信MyClass.class可以抛出它(它可能会抛出ClassDefNotFoundError,但这是一个更普遍的问题)。此外,MyClass.class使用import语句,而Class.forname()要求您传入完全限定的类名。


当我被提醒时,MyClass.class没有初始化MyClass,因此不会调用静态初始值设定项。

答案 3 :(得分:0)

是的,可以说没有“类”实例变量。实际上,它存在于每个类中。 MyClass.class直接为MyClass获取Class实例。我不确定你对反射有多熟悉,但这可以让你开始使用它。您可以查看本教程,了解您可以执行的操作的一些示例: http://www.ibm.com/developerworks/library/j-dyn0603/

Reflection允许程序在运行时查看和修改自己的行为。它是一种“元编程”。