深入研究java.lang.Class类

合集下载

Java面向对象程序设计智慧树知到答案章节测试2023年

Java面向对象程序设计智慧树知到答案章节测试2023年

第一章测试1.下列选项中,可以正确配置classpath的命令是() A:set classpath=C:Files.0_15 B:classpath set : C:Files.0_15 C:classpath set =C:Files.0_15 D:set classpath : C:Files.0_15 答案:A2.在JDK安装目录下,用于存放可执行程序的文件夹是() A:bin B:db C:jreD:lib 答案:A3.下面关于Java程序的描述中,错误的是() A:不同操作系统上的Java虚拟机是相同的 B:Java程序运行时,必须经过编译和运行两个步骤。

C:.class 格式的文件是用来运行的 D:.java格式的源文件是用来编译的答案:A4.下列选项中,哪些选项用于构成JDK开发环境()。

A:Java运行工具B:Java编译工具 C:Java文档生成工具 D:Java打包工具答案:ABCD5.下列关于使用Javac命令编译后生成文件的说法中,正确的是() A:编译后生成文件的后缀名为.class B:编译后生成的文件可以在Java虚拟机中运行C:编译后生成的文件为二进制文件 D:编译后生成文件的后缀名为.java 答案:ABC6.下列目录中,哪些属于JDK安装后的子目录() A:jre目录 B:lib目录C:include目录 D:demo目录答案:ABC7.lib是library的缩写,用于存放Java类库或库文件。

( ) A:对 B:错答案:A8.如果classpath环境变量没有进行设置,Java虚拟机会自动将其设置为“.”,也就是当前目录。

( ) A:错 B:对答案:B9.在任意命令行窗口中执行javac命令,如果都能正常地显示帮助信息,说明系统path环境变量配置成功。

( ) A:对 B:错答案:A10.Eclipse只是一个框架和一组服务,所有功能都是将插件组件加入到Eclipse框架中来实现的。

fastjson到底做错了什么?为什么会被频繁爆出漏洞?

fastjson到底做错了什么?为什么会被频繁爆出漏洞?

fastjson到底做错了什么?为什么会被频繁爆出漏洞?fastjson⼤家⼀定都不陌⽣,这是阿⾥巴巴的开源⼀个JSON解析库,通常被⽤于将Java Bean和JSON 字符串之间进⾏转换。

前段时间,fastjson被爆出过多次存在漏洞,很多⽂章报道了这件事⼉,并且给出了升级建议。

但是作为⼀个开发者,我更关注的是他为什么会频繁被爆漏洞?于是我带着疑惑,去看了下fastjson的releaseNote以及部分源代码。

最终发现,这其实和fastjson中的⼀个AutoType特性有关。

从2019年7⽉份发布的v1.2.59⼀直到2020年6⽉份发布的 v1.2.71 ,每个版本的升级中都有关于AutoType的升级。

下⾯是fastjson的官⽅releaseNotes 中,⼏次关于AutoType的重要升级:1.2.59发布,增强AutoType打开时的安全性 fastjson1.2.60发布,增加了AutoType⿊名单,修复拒绝服务安全问题 fastjson1.2.61发布,增加AutoType安全⿊名单 fastjson1.2.62发布,增加AutoType⿊名单、增强⽇期反序列化和JSONPath fastjson1.2.66发布,Bug修复安全加固,并且做安全加固,补充了AutoType⿊名单 fastjson1.2.67发布,Bug修复安全加固,补充了AutoType⿊名单 fastjson1.2.68发布,⽀持GEOJSON,补充了AutoType⿊名单。

(引⼊⼀个safeMode的配置,配置safeMode后,⽆论⽩名单和⿊名单,都不⽀持autoType。

) fastjson1.2.69发布,修复新发现⾼危AutoType开关绕过安全漏洞,补充了AutoType⿊名单 fastjson1.2.70发布,提升兼容性,补充了AutoType⿊名单甚⾄在fastjson的开源库中,有⼀个Issue是建议作者提供不带autoType的版本:那么,什么是AutoType?为什么fastjson要引⼊AutoType?为什么AutoType会导致安全漏洞呢?本⽂就来深⼊分析⼀下。

javalang-python解析获取java代码的方法体

javalang-python解析获取java代码的方法体

javalang python解析获取java代码的方法体(原创实用版3篇)目录(篇1)1.介绍 Java 和 Python2.解析 Java 代码的方法体3.使用 Python 解析 Java 代码的方法体4.总结正文(篇1)一、介绍 Java 和 PythonJava 和 Python 是两种非常流行的编程语言。

Java 是一种面向对象的编程语言,具有跨平台性、安全性和简单性等特点,被广泛应用于企业级应用、桌面应用和移动应用等领域。

Python 则是一种高级编程语言,以其简洁的语法和强大的库支持,在数据分析、人工智能、网络编程等领域有着广泛的应用。

二、解析 Java 代码的方法体在 Java 代码中,方法体是用来实现特定功能的代码块。

一个方法通常由方法名、返回类型、参数列表和方法体组成。

例如:```javapublic int add(int a, int b) {return a + b;}```在这个例子中,方法名为"add",返回类型为"int",参数列表为"int a, int b",方法体为"return a + b;"。

三、使用 Python 解析 Java 代码的方法体Python 作为一种强大的编程语言,可以通过各种方式解析 Java 代码的方法体。

其中,使用 Python 解析 Java 代码的方法体,通常需要借助 Java 的反射 API 和 Python 的第三方库,例如:`java-反射库`和`pyjavac`。

下面是一个简单的示例,展示如何使用 Python 解析 Java 代码的方法体:1.首先,安装`java-反射库`和`pyjavac`库:```bashpip install java-reflection```2.编写 Java 代码:```javapublic class Main {public static void main(String[] args) {System.out.println("Hello, World!");}}```3.使用 Python 解析 Java 代码的方法体:```pythonimport ng.reflect.Methodclass Main:def __init__(self):passdef main(self, args):print("Hello, World!")if __name__ == "__main__":main = Main()main.main([])```在这个示例中,我们使用 Python 的反射 API,解析 Java 类的构造函数和`main`方法,并将它们转换为 Python 类的方法。

深入Java泛型(Java泛型擦除机制,使用泛型强转时机,擦除对复写影响,协变返回类型)

深入Java泛型(Java泛型擦除机制,使用泛型强转时机,擦除对复写影响,协变返回类型)

深⼊Java泛型(Java泛型擦除机制,使⽤泛型强转时机,擦除对复写影响,协变返回类型)1.Java中泛型的擦除机制Java中的泛型是伪泛型,这个”伪”体现在你在xxx.java源⽂件中使⽤的参数化类型并不会保留到编译后的xxx.class⽂件中,⽽是会被擦除掉, 保留原始类型.(raw type)例如:⾃定义类上的泛型/*GenericTest.java*/class GenericTest<T>{private T variable;public void setVariable(T variable){this.variable=variable;}public T getVariable(){return variable;}}javap –c –p GenericTest.class:Compiled from "GenericTest.java"class generic.GenericTest<T> {generic.GenericTest();Code:0: aload_01: invokespecial #12 // Method java/lang/Object."<init>":()V4: returnpublic void setVariable(T);Code:0: aload_01: aload_12: putfield #23 // Field variable:Ljava/lang/Object;5: returnpublic T getVariable();Code:0: aload_01: getfield #23 // Field variable:Ljava/lang/Object;4: areturn}对以上字节码解释:class generic.GenericTest<T> {generic.GenericTest();Code:0: aload_0 //将位置为0的对象引⽤局部变量压⼊栈//在这⾥将隐含的this引⽤压⼊栈 ,原因在下⾯阐述1: invokespecial #12 // Method java/lang/Object."<init>":()V//其实就是隐含的super();调⽤Object的⽆参构造函数4: return//从⽅法中返回,返回值为void,使⽤这条指令返回的类型必须为void//由此可见构造函数被编译器认为返回值为void,上⾯的Object中的构造函数返回值为V(void)public void setVariable(T);Code:0: aload_01: aload_1 //将位置为1的对象引⽤局部变量压⼊栈,相当于将局部变量variable压⼊栈2: putfield #23 // Field variable:Ljava/lang/Object;//该位置编译器给出注释:字段variable其类型为Object//由此可看出编译后类中使⽤的泛型被擦除为原始类型(Object)//putfield指令会把局部变量variable的值赋给this指向的对象//中字段variable,也就是this.variable=variable;5: returnpublic T getVariable();Code:0: aload_01: getfield #23 // Field variable:Ljava/lang/Object;//会将引⽤变量的值以⼀个字长的形式压⼊操作数栈//其实就是成员变量variable中的值,注意到这⾥variable的类型依然为Object4: areturn //从⽅法中返回引⽤类型的值,及variable的值}在最开始的aload_0指令把隐含的this引⽤压⼊栈,因为可能调⽤实例⽅法或实例变量会⽤到this.那么由此我们可以推断GenericTest.java在经过编译后类⽂件中的GenericTest.class相当于下⾯的源程序:class GenericTest{private Object variable;/*//默认构造函数public GenericTest(){super();}*/public void setVariable(Object variable){this.variable=variable;}public Object getVariable(){return variable;}}原始类型⽤第⼀个限定的类型变量来替换,如果没有给定限定类型就⽤Object替换,以上的例⼦没有给出限定类型,如果有上限:例如:class GenericTest2<T extends Animal>{private T name;void method_1(T t){=t;}void method_2(){method_1(name);}}class Animal{}反编译:Compiled from "GenericTest.java"class generic.GenericTest2<T extends generic.Animal> {generic.GenericTest2();Code:0: aload_01: invokespecial #12 // Method java/lang/Object."<init>":()V4: returnvoid method_1(T);Code:0: aload_01: aload_12: putfield #23 // Field name:Lgeneric/Animal;5: returnvoid method_2();Code:0: aload_01: aload_02: getfield #23 // Field name:Lgeneric/Animal;5: invokevirtual #27 // Method method_1:(Lgeneric/Animal;)V8: return}经过编译后相当于下⾯的源程序:class GenericTest2{private Animal name;void method_1(Animal t){=t;}void method_2(){method_1(name);}}2.Java使⽤泛型后的强转时机:既然你编译器把泛型擦除为原始类型,那么我们为什么⼜不需要强转为需要的类型,反⽽可以直接使⽤???⼀步⼀步来说明:例如:class GenericMainClass{public static void main(String[] args){GenericTest<Integer> gt=new GenericTest<Integer>();Integer in=gt.getVariable();}}反编译:Compiled from "GenericTest.java"class generic.GenericMainClass {generic.GenericMainClass();Code:0: aload_01: invokespecial #8 // Method java/lang/Object."<init>":()V4: returnpublic static void main(ng.String[]);Code:0: new #16 // class generic/GenericTest//new GenericTest();new指令会把该对象的引⽤压⼊栈3: dup //复制栈顶内容(该对象的引⽤),把复制内容压⼊栈,此时保存了该对象两份引⽤//为什么要保留⼀份该对象的引⽤?因为下⾯会⽤该引⽤指明构造函数4: invokespecial #18 // Method generic/GenericTest."<init>":()V//需要弹出⼀个引⽤调⽤GenericTest的构造函数进⾏初始化7: astore_1 //从栈中弹出⼀个引⽤赋值给1号局部变量1就是gt,第⼆次⽤到该对象引⽤8: aload_19: invokevirtual #19 // Method generic/GenericTest.getVariable:()Ljava/lang/Object;//调⽤了getVariable⽅法,返回值类型为Object12: checkcast #23 // class java/lang/Integer//此指令由Integer in=gt.getVariable();引发,在这⾥为了检测能否完成从Object->//Ineteger转换,//相当于(Integer)gt.getVariable(),如果不能强转//抛出ClassCastException15: astore_216: return}由此可见:Integer in=gt.getVariable();编译器把这个⽅法的调⽤翻译为两条虚拟机指令:1. 对原始⽅法getVariable()调⽤ (invokevirtual)2. 将返回值的Object类型强制转换为Integer类型(checkcast)如果纯粹的只⽤gt.getVariable()是不会涉及到强制转换的,也即是说在需要的时候,编译器会⾃动插⼊强制类型转化.3.Java中泛型擦除对⽅法复写的影响我们通过举例来引出问题:class CopyTest<T>{public T get(T t){return t;}}class Son extends CopyTest<String>{public String get(String t){return t;}}由于java中的泛型有擦除机制,那么CopyTest.class与Son.class相当于以下源程序:class CopyTest{public Object get(Object t){return t;}}class Son extends CopyTest{public String get(String t){return t;}}可以看到Son中的get⽅法并没有复写CopyTest中的get⽅法,因为参数列表都不相同,何谈复写?但是的确完成了复写,如何完成的呢?反编译Son.class:Compiled from "GenericTest.java"class generic.Son extends generic.CopyTest<ng.String> {generic.Son();Code:0: aload_01: invokespecial #8 // Method generic/CopyTest."<init>":()V4: returnpublic ng.String get(ng.String);Code:0: aload_11: areturnpublic ng.Object get(ng.Object);Code:0: aload_01: aload_12: checkcast #19 // class java/lang/String5: invokevirtual #21 // Method get:(Ljava/lang/String;)Ljava/lang/String;8: areturn}对于以上指令,如果⽤Java代码体现就是:class Son extends CopyTest{public Object get(Object obj){this.get((String)obj);}public String get(String t){return t;}}Object get(Object)⽅法就是为了完成复写动作编译器⾃动⽣成的桥⽅法(bridge method),可以看到桥⽅法间接的调⽤了String get(String),达到我们主观上的”复写”.4.Java中的协变返回类型:在Jdk 1.4及以前,⼦类⽅法如果要覆盖超类的某个⽅法,必须具有完全相同的⽅法签名,包括返回值也必须完全⼀样。

JAVA反射机制之Class类API实例介绍 - AJava

JAVA反射机制之Class类API实例介绍 - AJava

JAVA反射机制之Class类API实例介绍- AJavaJAVA反射机制之Class类API实例介绍核心提示:本文针对jdk6.0中ng.Class类的API进行了简单的实例应用,例子简单易懂,比较适合入门级阅读。

实例简介:/* *IncludeInnerClass类中包含了三种访问控制的内部类,并且以这三个内部类的引用对象和一个整型数作为属性,在外部类的方法中分别调用了内部本文针对jdk6.0中ng.Class类的API进行了简单的实例应用,例子简单易懂,比较适合入门级阅读。

实例简介:/**IncludeInnerClass类中包含了三种访问控制的内部类,并且以这三个内部类的引用对象和一个整型数作为属性,在外部类的方法中分别调用了内部类的方法*外部类有两个构造方法,一个默认构造方法,一个带一个整型参数的构造方法*Class类的API大家可以直接查阅jdk手册*getMethods()系列方法基本与getConstructors()系列方法类似,仅在后序文章中对getMethods()系列方法的一个特例做深入介绍,将涉及covariant return type 和bridge methods。

*/package classTest;import ng.reflect.Field;import ng.reflect.Modifier;import ng.reflect.Constructor;import ng.reflect.Method;class IncludeInnerClass implements Runnable{class DefaultInnerClass{int i;public DefaultInnerClass(){}DefaultInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am DefaultInnerClass.");}}private class PrivateInnerClass{int i;PrivateInnerClass(){}PrivateInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am PrivateInnerClass.");}}public class PublicInnerClass{int i;public PublicInnerClass(){}PublicInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am PublicInnerClass.");}}DefaultInnerClass deic;private PrivateInnerClass pric;public PublicInnerClass puic;int i;public IncludeInnerClass(){deic = new DefaultInnerClass(1);pric = new PrivateInnerClass(2);puic = new PublicInnerClass(3);this.i=10;}private IncludeInnerClass(int i){deic = new DefaultInnerClass(1);pric = new PrivateInnerClass(2);puic = new PublicInnerClass(3);this.i=i;}public void method(){deic.innerMethod();pric.innerMethod();puic.innerMethod();}public void run(){method();}}public class GetInnerClassTest {public static void main(String[] args) throws SecurityException{//直接生成外部类的对象,并调用外部类的方法IncludeInnerClass iic = new IncludeInnerClass();System.out.println("regular use of outer class object.");iic.method();System.out.println("+++++++++++++++++++++++++++++ ++++++");//如何生成内部类对象:必须通过外部类实例IncludeInnerClass.DefaultInnerClass iicdic = iic.new DefaultInnerClass(2);System.out.println("regular use of inner class object.");System.out.println(iicdic.i);iicdic.innerMethod();System.out.println("+++++++++++++++++++++++++++++ ++++++");//动态加载外部类并通过getDeclaredClasses()得到其包含的内部类名称Class&lt;?&gt; clc = iic.getClass();Class&lt;?&gt;[] classArray =clc.getDeclaredClasses();System.out.println("print inner class name.");for(int i=0;i&lt;classArray.length;i++){System.out.println(classArray[i].getName());}System.out.println("+++++++++++++++++++++++++++++++++++");//动态加载内部类,调用getDeclaringClass()得到其外部类Class&lt;?&gt; clac = iicdic.getClass();Class&lt;?&gt; outClass =clac.getDeclaringClass();System.out.println("print outer class name.");System.out.println(outClass.getName());//如果没有外部类则返回null,小心空指针异常System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到所在的包Package pack;pack = clc.getPackage();System.out.println("print package name.");System.out.println(pack.getName());System.out.println(pack.equals(clac.getPackage()));//内部类和外部类的包名相同System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类继承的接口Class&lt;?&gt;[] interfaceArray =clc.getInterfaces();System.out.println("print interface name.");for(int i=0;i&lt;interfaceArray.length;i++){System.out.println(interfaceArray[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的属性Field[] field = clc.getDeclaredFields();System.out.println("print outer class fields");for(int i=0;i&lt;field.length;i++){System.out.println(Modifier.toString(field[i].getModifiers())+" "+field[i].getType().getName()+" "+field[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的指定属性Field f = null;try {f = clc.getDeclaredField("pric");} catch (NoSuchFieldException e) {System.out.println("no such Field.");}System.out.println("print the field we want.");System.out.println(Modifier.toString(f.getModifiers())+" "+f.getType().getName()+" "+f.getName());System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的所有构造函数及其修饰符和参数:getDeclaredConstructors()得到所有的构造函数Constructor&lt;?&gt;[] allConArray =clc.getDeclaredConstructors();System.out.println("print all constructor of outer class.");for(int i=0;i&lt;allConArray.length;i++){System.out.println("-----------------------------------");System.out.println("print modifier and name");System.out.println(Modifier.toString(allConArray[i].getModi fiers())+" "+allConArray[i].getName());System.out.println("print parameter type");Class&lt;?&gt;[] caparam =allConArray[i].getParameterTypes();for(int j=0;j&lt;caparam.length;j++){System.out.println(caparam[j].getName());}}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类所有public的构造函数:getConstructor()Constructor&lt;?&gt;[] publicCon =clc.getConstructors();System.out.println("print all public constructor of outer class.");for(int i=0;i&lt;publicCon.length;i++){System.out.println(Modifier.toString(publicCon[i].getModifi ers())+" "+publicCon[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到指定的外部类构造函数getDeclaredConstructor(Class&lt;?&gt;[]),形参为指定构造函数的参数类型数组Class&lt;?&gt;[] parameterTypes = new Class[1];parameterTypes[0] = int.class;Constructor&lt;?&gt; con = null;try {con =clc.getDeclaredConstructor(parameterTypes);} catch (NoSuchMethodException e) {System.out.println("NO SUCH CONSTURCTOR!!!");}System.out.println("we want the constructor with one parameter.");System.out.println(Modifier.toString(con.getModifiers())+" "+con.getName());System.out.println(con.getParameterTypes()[0].getName() );System.out.println("+++++++++++++++++++++++++++++ ++++++");//Method类与Constructor基本一致,这里不做介绍。

Java 类加载原理解析

Java 类加载原理解析

Java类加载原理解析分类:java应用2010-07-14 14:07 55人阅读评论(0) 收藏举报Java类加载原理解析1基本信息摘要:每个java开发人员对ng.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java 技术体系中的类加载。

Java的类加载机制是java技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚拟机的连接模型和java语言的动态性都有很大帮助。

由于关于java类加载的内容较多,所以打算分三篇文章简述一下:第一篇:java类加载原理解析第二篇:插件环境下类加载原理解析第三篇:线程上下文类加载器分类:开发技术->J2EE标签:Java类加载类加载器双亲委派机制自定义类加载器作者:朱兴创建于2007-6-22MSN:zhu_xing@2Java虚拟机类加载器结构简述2.1JVM三种预定义类型类加载器我们首先看一下JVM预定义的三种类型类加载器,当一个JVM 启动的时候,Java 缺省开始使用如下三种类型类装入器:启动(Bootstrap)类加载器:引导类装入器是用本地代码实现的类装入器,它负责将<Java_Runtime_Home>/lib 下面的类库加载到内存中。

由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

标准扩展(Extension)类加载器:扩展类加载器是由Sun 的ExtClassLoader(uncher$ExtClassLoader)实现的。

它负责将< Java_Runtime_Home >/lib/ext 或者由系统变量java.ext.dir 指定位置中的类库加载到内存中。

开发者可以直接使用标准扩展类加载器。

系统(System)类加载器:系统类加载器是由Sun 的AppClassLoader(uncher$AppClassLoader)实现的。

Java语言中的Class类

Java语言中的Class类

Java语⾔中的Class类基本概念在Object类中定义了以下的⽅法,此⽅法将被所有⼦类继承public final Class getClass()这个⽅法的返回值类型是⼀个Class类,此类是Java反射的源头,是实际上所谓反射从程序的运⾏结果来看也很好理解,即:可以通过对象反射求出类的名称。

对象照镜⼦后可以得到的信息:某个类的属性、⽅法和构造器、某个类到底实现了哪些接⼝。

对于每个类⽽⾔,JRE都为其保留⼀个不变的Class类型的对象。

⼀个Class对象包含了特定某个结构(class、interface、enum、annotation、primitive type、void)的有关信息。

Class本⾝也是⼀个类Class对象只能由系统建⽴对象⼀个加载的类在JVM中只会有⼀个Class实例⼀个Class对象对应的是⼀个加载到JVM中的⼀个.class⽂件每个类的实例都会记得⾃⼰是由哪个Class实例所⽣成通过Class可以完整地得到⼀个类中的所有被加载结构Class类是Reflection的根源,针对任何你想动态加载、运⾏的类,唯有先获得相应的Class对象。

Java中拥有Class对象的类型在Java语⾔中,⼀切皆是对象。

⽽对象主要分为两种,⼀种是普通类创建的实例对象,⼀种是Class类对象。

每个类运⾏时的类型信息就是通过Class对象表⽰的,这个对象包含了与类有关的信息。

其实Java中的实例对象就是通过Class对象来创建的,Java使⽤Class对象执⾏其RTTI(运⾏时类型识别,Run-Time Type Identification),多态是基于RTTI实现的。

那么在Java中哪些类型可以有Class对象呢?class:外部类、成员(成员内部类、静态内部类)、局部内部类、匿名内部类interface:接⼝[]:数组enum:枚举annotation:注解@interfaceprimitive type:基本数据类型void我们⽤代码演⽰⼀下,这些类型的Class对象都是什么?Class c1 = Object.class; // 类Class c2 = Comparable.class; // 接⼝Class c3 = String[].class; // ⼀维数组Class c4 = int[][].class; // ⼆维数组Class c5 = Override.class; // 注解Class c6 = ElementType.class; // 枚举Class c7 = Integer.class; // 基本数据类型(包装类)Class c10 = int.class; // 基本数据类型Class c8 = void.class; // 空类型Class c9 = Class.class; // ClassSystem.out.println(c1); // class ng.ObjectSystem.out.println(c2); // interface parableSystem.out.println(c3); // class [ng.String;System.out.println(c4); // class [[ISystem.out.println(c5); // interface ng.OverrideSystem.out.println(c6); // class ng.annotation.ElementTypeSystem.out.println(c7); // class ng.IntegerSystem.out.println(c10);// intSystem.out.println(c8); // voidSystem.out.println(c9); // class ng.Classint[] a = new int[10];int[] b = new int[100];/*对于数组,只要元素类型与维度⼀样,就是同⼀个Class对象*/System.out.println(a.getClass()); //class [ISystem.out.println(b.getClass()); //class [ISystem.out.println(b.getClass().hashCode()); //1735600054System.out.println(a.getClass().hashCode()); //1735600054每⼀个类都有⼀个Class对象,每当编译⼀个新类就产⽣⼀个Class对象,更准确的来说,是被保存在⼀个同名的.class⽂件中。

Java中的Class类

Java中的Class类

Java中的Class类Class 类是在Java语⾔中定义⼀个特定类,他⽤来存储类的信息,类似C#的Type类,存储类的定义包含成员变量,成员⽅法,还有这个类实现的接⼝,以及这个类的⽗类等等信息。

我们可以通过类的class属性来快捷的获取到他的类型,也可以通过对象的getClass()函数获取到他的类型,还可以通过Class的forName ⽅法获取。

代码如下:String str= "kiba";str.getClass();Class stringClass = String.class;Class userClass = H_User.class;Class t= Class.forName("ng.Thread");获得到类的类型后,就可以调⽤它的函数,来获取对应的内容。

stringClass.getClassLoader();stringClass.getComponentType();⽅法如下:getClassLoader()获取该类的类装载器。

getComponentType()如果当前类表⽰⼀个数组,则返回表⽰该数组组件的Class对象,否则返回null。

getConstructor(Class[])返回当前Class对象表⽰的类的指定的公有构造⼦对象。

getConstructors()返回当前Class对象表⽰的类的所有公有构造⼦对象数组。

getDeclaredConstructor(Class[])返回当前Class对象表⽰的类的指定已说明的⼀个构造⼦对象。

getDeclaredConstructors()返回当前Class对象表⽰的类的所有已说明的构造⼦对象数组。

getDeclaredField(String)返回当前Class对象表⽰的类或接⼝的指定已说明的⼀个域对象。

getDeclaredFields()返回当前Class对象表⽰的类或接⼝的所有已说明的域对象数组。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

作者:熔岩
日期:2007-01-16
MSN :leizhimin@
声明:原创作品,未经授权,谢绝转载!
前言:Java的类库日益庞大,所包含的类和接口也不计其数。

但其中有一些非常重要的类和接口,是Java类库中的核心部分。

常见的有String、Object、Class、Collection、ClassLoader...,熟悉这些类是学好Java的基础。

而这些类一般不容易理解,需要做深入的研究和实践才能掌握。

下面是我对这些类理解和使用的一些总结。

欢迎你在阅读后将你宝贵的意见和读后感留下!
Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。

这项信息纪录了每个对象所属的类。

虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。

Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。

Class 没有公共构造方法。

Class 对象是在加载类时由Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的,因此不能显式地声明一个Class对象。

虚拟机为每种类型管理一个独一无二的Class对象。

也就是说,每个类(型)都有一个Class对象。

运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。

如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。

基本的Java 类型(boolean、byte、char、short、int、long、float 和double)和关键字void 也都对应一个Class 对象。

每个数组属于被映射为Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class 对象。

一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。

一、如何得到Class的对象呢?有三种方法可以的获取:
1、调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。

例如:
MyObject x;
Class c1 = x.getClass();
2、使用Class类的中静态forName()方法获得与字符串对应的Class对象。

例如:
Class c2=Class.forName("MyObject"),Employee必须是接口或者类的名字。

3、获取Class类型对象的第三个方法非常简单。

如果T是一个Java类型,那么T.class就代表了匹配的类对象。

例如
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
注意:Class对象实际上描述的只是类型,而这类型未必是类或者接口。

例如上面的int.class是一个Class类型的对象。

由于历史原因,数组类型的getName方法会返回奇怪的名字。

二、Class类的常用方法
1、getName()
一个Class对象描述了一个特定类的属性,Class类中最常用的方法getName以String 的形式返回此Class 对象所表示的实体(类、接口、数组类、基本类型或void)名称。

2、newInstance()
Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。

例如:
x.getClass.newInstance(),创建了一个同x一样类型的新实例。

newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。

3、getClassLoader()
返回该类的类加载器。

4、getComponentType()
返回表示数组组件类型的Class。

5、getSuperclass()
返回表示此Class 所表示的实体(类、接口、基本类型或void)的超类的Class。

6、isArray()
判定此Class 对象是否表示一个数组类。

三、Class的一些使用技巧
1、forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象。

例如
Object obj = Class.forName(s).newInstance();
2、虚拟机为每种类型管理一个独一无二的Class对象。

因此可以使用==操作符来比较类对象。

例如:
if(e.getClass() == Employee.class)...
四、来自SUN公司的ng.Class类的API文档,网上有chm中文版的,很好找。

为了查阅方便,我从SUN公司的JavaDoc站点上复制出来了Class类的API文档。

ng
类Class<T>
ng.Object
ng.Class<T>
所有已实现的接口:
Serializable, AnnotatedElement, GenericDeclaration, Type
public final class Class<T>
extends Object
implements Serializable, GenericDeclaration, Type, AnnotatedElement
Class类的实例表示正在运行的Java 应用程序中的类和接口。

枚举是一种类,注释是一种接口。


个数组属于被映射为Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。

基本的Java 类型(boolean、byte、char、short、int、long、float和double)和关键字void也表示为Class对象。

Class没有公共构造方法。

Class对象是在加载类时由Java 虚拟机以及通过调用类加载器中的defineClass方法自动构造的。

以下示例使用Class对象来显示对象的类名:
void printClassName(Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}
还可以使用一个类字面值(JLS Section 15.8.2)来获得命名类型(或void)的Class对象。

例如: System.out.println("The name of class Foo is: "+Foo.class.getName());
从以下版本开始:
JDK1.0
另请参见:
ClassLoader.defineClass(byte[], int, int), 序列化表格。

相关文档
最新文档