简体   繁体   English

什么是MyClass.class?

[英]what is MyClass.class?

following is the code listed in MainClass.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... i found the article quite useful. thnx coobird ...我发现这篇文章很有用。 :) :)

But, about litereals my knowledge is only limited to: 但是,关于litereals,我的知识仅限于:

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

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

the only non-primitive litereal, i know is 我知道唯一的非原始版

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

and class literal, which u and Jon Skeet make clear to me very well. 和类字面量,你和乔恩·斯基特(Jon Skeet)对我很清楚。

are there more literals found in java??? 在Java中找到更多文字了吗???


agreed... so as per the discussion, total literals are categorized as:- 同意...因此,根据讨论,总字面量归类为:

  • primitive literals 原始文字
  • string literals 字符串文字
  • class literal 类文字
  • null 空值

are there some more literals (to make the list a little longer :) ) 还有更多的文字(使列表更长一些:)


when i decompile the MainClass.class using decomipler, two Class type static variables (may be coz, i have used class literal 2 times) are found to be automatically added, but never found to be used in the code. 当我使用反编译器反编译MainClass.class时,发现会自动添加两个Class类型的静态变量(可能是coz,我已经使用了2个类常量),但从未在代码中使用它们。 Also, both the class literals are directly replaced from the class file where i have used them in the java file. 同样,两个类文字都直接从我在java文件中使用过的类文件中替换。

My code :- 我的代码:-

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...");
    }
}

Decompiler generated code :- 反编译器生成的代码:-

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;
}

It's "class literal" - a simple way of getting the Class<T> for a particular type. 它是“类文字”-一种获取特定类型的Class<T>的简单方法。

See section 15.8.2 of the Java Language Specification for more details. 有关更多详细信息,请参见Java语言规范的15.8.2节

Note that it's not a "field" of the class, it's a special piece of syntactic sugar. 请注意,这不是类的“领域”,而是一块特殊的语法糖。

Due to type erasure, you may run into interesting restrictions around generics. 由于类型擦除,您可能会遇到有关泛型的有趣限制。 The TypeLiteral introduced in Guice gives more information and a workaround. Guice中引入的TypeLiteral提供了更多信息和解决方法。

In terms of implementation, it depends on which bytecode version you're targeting. 在实现方面,这取决于您要定位的字节码版本。 If you use -target 1.4 (or below), a call to Class.forName() is inserted into your code in a static method which is called during type initialization. 如果使用-target 1.4 (或更低版本),则将在类型初始化期间调用的静态方法中Class.forName()的调用插入到您的代码中。 If you use -target 1.5 (or above) the constant pool gets a "class" entry. 如果使用-target 1.5 (或更高版本),则常量池将获得一个“类”条目。 I don't know the details of how this is handled though. 我不知道如何处理这个细节。

Writing MyClass.class gives an object of the type Class<MyClass> . 编写MyClass.class会给出Class<MyClass>类型的对象。

So, in the above code, if one is to use generics correctly, it should rather say: 因此,在上面的代码中,如果要正确使用泛型,它应该说:

Class<MyClass> c = MyClass.class;

or 要么

Class<?> c = MyClass.class;

The class keyword will give the Class object that models the class. class关键字将提供对Class进行建模的Class对象。

As mentioned by Jon Skeet, Section 15.8.2: Class Literals of The Java Language Specification says the following about the class literal: 正如Jon Skeet所提到的, 《 Java语言规范 》的15.8.2节:类文字 描述了有关类文字的以下内容:

A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' 类文字是由类,接口,数组或原始类型的名称或伪类型void组成的表达式,后跟“。”。 and the token class . 和令牌class The type of a class literal, C.Class , where C is the name of a class, interface or array type, is Class<C> . 类文字的类型C.Class ,其中C是类,接口或数组类型的名称,是Class<C>

A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance. 类文字将根据当前实例的类的定义类加载器所定义的命名类型(或为void)对Class对象求值。

To add to what others have already said, "MyClass.class" is semantically identical to: 要补充别人已经说过的话,“ MyClass.class”在语义上等同于:

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

where "classloader" is the ClassLoader instance of the calling class. 其中“ classloader”是调用类的ClassLoader实例。

The main difference is in exception handling - with the above code fragment throws ClassNotFoundException, but I don't believe that MyClass.class can throw that (it may throw ClassDefNotFoundError, however, but that's a more general issue). 主要区别在于异常处理-上面的代码片段引发了ClassNotFoundException,但我不相信MyClass.class会引发该异常(但是,它可能引发ClassDefNotFoundError,但这是一个更普遍的问题)。 Also, MyClass.class works with import statements, whereas Class.forname() requires you to pass in the fully-qualified class name. 此外,MyClass.class可以与import语句一起使用,而Class.forname()则要求您传入完全限定的类名。


As I was reminded, MyClass.class does not initialize MyClass, so the static initializer won't be called. 提醒我,MyClass.class不会初始化MyClass,因此不会调用静态初始化程序。

Right, there's no "class" instance variable so to speak. 是的,可以说没有“类”实例变量。 It exists in every class, actually. 实际上,它存在于每个类中。 MyClass.class gets the Class instance directly for MyClass. MyClass.class直接获取MyClass的Class实例。 I'm not sure how familiar you are with reflection, but this allows you start working with that. 我不确定您对反射有多熟悉,但这可以让您开始进行思考。 You might check out this tutorial for some examples of what you can do: http://www.ibm.com/developerworks/library/j-dyn0603/ 您可以查看本教程以获取一些可以做的事的示例: http : //www.ibm.com/developerworks/library/j-dyn0603/

Reflection allows programs to view and modify their own behavior at runtime. 反射允许程序在运行时查看和修改自己的行为。 Its a type of "metaprogramming." 它是一种“元编程”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM