首页 > 编程知识 正文

getclass返回结果使用,getclassloader加载

时间:2023-05-05 19:58:59 阅读:128524 作者:4899

1、理解类Class :类Class包含类的信息,如方法、方法和属性,可用于反射。 以下是所有方法

2、获取Class类对象的几种方法:

测试测试=new test (;

(1).test.getClass );

因为在运行时进行确认,所以运行实例就是这样的对象。 super.getClass ()无法获取父类的类对象。 仍然是当前的类对象。

获取父类对象: test.getClass ().getSuperclass () )。

class Father{

公共语音showname (

{

system.out.println('father . ';

}

}

class Child extends Father{

公共语音showname (

{

system.out.println(children );

}

}

Father father=new Child (;

system.out.println (father.class; 结果是Father

system.out.println (father.getclass () ); 结果是Child

(2).Test.class;

在编译时确认,并返回当前类的类对象实例。 不加载静态变量

获取父类对象: Test.class.getSuperclass (

(3).Class.forName (“类路径”); 将加载静态变量。 例如,jdbc驱动程序可以使用它来加载一些静态属性

使用静态方法获取类对象,class.forname('com.wan.test );

如果尝试在运行时生成类的对象,Java虚拟机(JVM )将检查是否加载了该类型的类对象。 如果未加载,JVM将根据类的名称找到并加载. class文件。 一种类型的Class对象加载到内存中后,可以使用它来生成该类型的所有对象

普通班为什么不能用静态修饰?

谈谈个人的理解吧。 静态限定的东西由我们成为类成员,它随类的加载而加载。 例如,静态代码块、静态成员、静态方法(这里只是加载,没有调用)等等。 如果将Class文件中的外部类设置为静态,其目的是什么? 是否要在APP启动时加载此类? 如果在这次使用中完全没有使用过这个类,会不会浪费内存呢? 这样设计不合理。 总之,在设计不合理的地方,Java是不存在的。

为什么内部类可以使用静态限定,是因为内部类是类的成员。 如果不使用静态限定,则在创建内部类时首先需要外部类的对象。 如果使用内部类,则内存中始终存在对外部类的引用,但如果只使用内部类而不需要外部类,则可能会浪费内存,导致内存溢出。 如果使用静态限定内部类,则内部类在创建对象时不需要对外部类对象的引用。

最后得出的结论是,静态可以用于限定内部类,但不能用于限定外部类

3、关于类加载器的理解

请在Eclipse中创建新类并运行。

package java.lang;

公共类长{

publicstaticvoidmain (字符串[ ] args ) {

系统. out.println (hi,i am here );

}

}

你能推测它的运行吗? 好啊。 如下所示。

错误在:类java.lang.Long中找不到main方法。 请将main方法定义为3360

publicstaticvoidmain (字符串[ ] args ) )。

否则,Java FX APP应用程序类必须扩展javafx.application.Application

因为,我在Long方法类中定义了main方法,为什么没有定义main方法呢?

本文将解决上述问题的原因。

二.类加载器的作用

我们知道,java程序编写完成后,它作为. java (文本文件)文件存在于磁盘上。 然后,使用(深色眼睛/javac.exe )编译命令将. java文件编译为. class文件),并将其驻留在磁盘上。 但是,要运行程序,必须首先将. class文件加载到JVM内存中,才能使用。 classLoader负责将磁盘上的. class文件加载到JVM内存中,如下图所示。

我想每个Class对象都有磁盘上. Class字节码的内容,每个Class对象都有getClassLoader ()方法,这样就可以知道是谁从. Class文件中加载了我

到内存中变成Class对象的。

三、ClassLoader层次结构

请执行如下程序:

public class Test {

public static void main(String[] args) {

ClassLoader classLoader = Test.class.getClassLoader();

System.out.println(classLoader);

ClassLoader classLoader1 = classLoader.getParent();

System.out.println(classLoader1);

ClassLoader classLoader2 = classLoader1.getParent();

System.out.println(classLoader2);

}

}

它的输出是:

sun.misc.Launcher$AppClassLoader@2a139a55

sun.misc.Launcher$ExtClassLoader@7852e922

null

得到了 classLoader2就是null值了。这里其实有三个类加载器:

(1): 根类加载器(null)

它是由本地代码(c/c++)实现的,你根本拿不到他的引用,但是他实际存在,并且加载一些重要的类,它加载(%JAVA_HOME%jrelib),如rt.jar(runtime)、i18n.jar等,这些是Java的核心类。

(2): 扩展类加载器(ExtClassLoader)

虽说能拿到,但是我们在实践中很少用到它,它主要加载扩展目录下的jar包, %JAVA_HOME%libext

(3): 应用类加载器(AppClassLoader)

它主要加载我们应用程序中的类,如Test,或者用到的第三方包,如jdbc驱动包等。

这里的父类加载器与类中继承概念要区分,它们在class定义上是没有父子关系的。

四、Class加载时调用类加载器的顺序

当一个类要被加载时,有一个启动类加载器和实际类加载器的概念,这个概念请看如下分析

如上面的Test.class要进行加载时,它将会启动应用类加载器进行加载Test类,但是这个应用类加载器不会真正去加载他,而是会调用看是否有父加载器,结果有,是扩展类加载器,扩展类加载器也不会直接去加载,它看自己是否有父加载器没,结果它还是有的,是根类加载器。

所以这个时候根类加载器就去加载这个类,可在%JAVA_HOME%jrelib下,它找不到com.Test这个类,所以他告诉他的子类加载器,我找不到,你去加载吧,子类扩展类加载器去%JAVA_HOME%libext去找,也找不着,它告诉它的子类加载器 AppClassLoader,我找不到这个类,你去加载吧,结果AppClassLoader找到了,就加到内存中,并生成Class对象。

这个时间时候启动类加载器(应用类加载器)和实际类加载器(应用类加载器)是同一个.

这就是Java中著名的委托加载机制,看如下图:

我们再来看一下 java.lang.Long的加载,按上面分析,应该是由根类加载器加载得到的,此时启动类加载器是应用类加载器,但实际类加载器是根类加载器。

所以回到我们最开始那个问题,没有main方法是因为执行的根本不是我们自己写的类,执行的是java核心中的那个Long类,当然没有main方法了。 这样就防止我们应用中写的类覆盖掉java核心类。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。