class="markdown_views prism-atom-one-dark">
一、前言:
在说明Class类的静态方法forName()之前,先清楚有关Class类的几个概念:
1、 Class类封装了类或接口的运行时状态
Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,这些标示纪录了每个对象所属的类。
虚拟机通常使用运行时类型信息选择正确方法去执行,用来保存这些类型信息的类是Class类。
2、Class类型的对象,是加载类时自动创建的
Class 没有公共构造方法。Class 对象是在加载类时,由Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
3、虚拟机为每种类型管理一个独一无二的Class对象
每个类(型)都有一个Class对象。
运行程序时,Java虚拟机(JVM)首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class 文件,并将其Class对象载入。
1.基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 2.每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。 3.一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
以上说法查看Class源码会发现,Book.class .getName()
最终调用的:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">private class="token keyword">transient class="token class -name">String nameclass="token punctuation">;
class="token keyword">public class="token class -name">String class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">{
class="token class -name">String name class="token operator">= class="token keyword">this class="token punctuation">. nameclass="token punctuation">;
class="token keyword">if class="token punctuation">( name class="token operator">== class="token keyword">null class="token punctuation">)
class="token keyword">this class="token punctuation">. name class="token operator">= name class="token operator">= class="token function">getName0 class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token keyword">return nameclass="token punctuation">;
class="token punctuation">}
此时Book也是一个独一无二的Class对象,即对象中的对象。
二、案例:
Book.class ="tags" href="/tags/JAVA.html" title=java>java类
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package class="token namespace">comclass="token punctuation">. junitclass="token punctuation">. demo class="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">Book class="token punctuation">{
class="token keyword">private class="token keyword">static class="token keyword">final class="token class -name">String defName class="token operator">= class="token string">"《程序猿植发》" class="token punctuation">;
class="token keyword">static class="token punctuation">{
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"我是静态代码块,输出: " class="token operator">+ defNameclass="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">//打印生产日期:
class="token keyword">public class="token keyword">static class="token class -name">String class="token function">printProduceDate class="token punctuation">( class="token class -name">String nameclass="token punctuation">) class="token punctuation">{
class="token keyword">return class="token string">"我是静态方法printProduceDate,输出: " class="token operator">+ name class="token operator">+ class="token string">", produce is:" class="token operator">+ class="token class -name">System class="token punctuation">. class="token function">currentTimeMillis class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token keyword">private class="token class -name">String nameclass="token punctuation">;
class="token keyword">public class="token class -name">Book class="token punctuation">( class="token punctuation">) class="token punctuation">{
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"我是Book声明的构造方法!" class="token punctuation">) class="token punctuation">;
name class="token operator">= defNameclass="token punctuation">;
class="token punctuation">}
class="token keyword">public class="token class -name">String class="token function">toString class="token punctuation">( class="token class -name">String msgclass="token punctuation">) class="token punctuation">{
class="token keyword">return name class="token operator">+ msgclass="token punctuation">;
class="token punctuation">}
class="token punctuation">}
执行方法:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">public class="token keyword">static class="token keyword">void class="token function">main class="token punctuation">( class="token class -name">String class="token punctuation">[ class="token punctuation">] argsclass="token punctuation">) class="token keyword">throws class="token class -name">ClassNotFoundException class="token punctuation">, class="token class -name">NoSuchMethodException class="token punctuation">, class="token class -name">InvocationTargetException class="token punctuation">, class="token class -name">IllegalAccessException class="token punctuation">, class="token class -name">InstantiationException class="token punctuation">{
class="token comment">//1-将指定类加载到JVM中(ClassNotFoundException)
class="token class -name">Class aClass class="token operator">= class="token class -name">Class class="token punctuation">. class="token function">forName class="token punctuation">( class="token string">"com.junit.demo.Book" class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( aClassclass="token punctuation">) class="token punctuation">;
class="token comment">//2.1-访问静态方法:NoSuchMethodException,InvocationTargetException
class="token class -name">Method method class="token operator">= aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"printProduceDate" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
class="token class -name">String result class="token operator">= class="token punctuation">( class="token class -name">String class="token punctuation">) methodclass="token punctuation">. class="token function">invoke class="token punctuation">( aClassclass="token punctuation">, class="token string">"《程序猿的颈椎自传》" class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( resultclass="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"---------------------------\n" class="token punctuation">) class="token punctuation">;
class="token comment">//2.2-初始化对象:
class="token class -name">Book obj class="token operator">= class="token punctuation">( class="token class -name">Book class="token punctuation">) aClassclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"得到对象后访问get方法:" class="token operator">+ objclass="token punctuation">. class="token function">toString class="token punctuation">( class="token string">"" class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"---------------------------\n" class="token punctuation">) class="token punctuation">;
class="token comment">//2.3-初始化对象后访问方法:
class="token class -name">Method method3 class="token operator">= aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"toString" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
class="token class -name">String result3 class="token operator">= class="token punctuation">( class="token class -name">String class="token punctuation">) method3class="token punctuation">. class="token function">invoke class="token punctuation">( aClassclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token punctuation">) class="token comment">/*obj*/ class="token punctuation">, class="token string">"这本书是我的伙伴!" class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( result3class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"---------------------------\n" class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token class -name">Book class="token punctuation">. class="token keyword">class class="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">我是静态代码块,输出class="token operator">: 《程序猿植发》
class="token keyword">class class="token class -name">class="token namespace">comclass="token punctuation">. junitclass="token punctuation">. democlass="token punctuation">. Book
我是静态方法printProduceDate,输出class="token operator">: 《程序猿的颈椎自传》class="token punctuation">, produce isclass="token operator">: class="token number">1626682894095
class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-
我是class="token class -name">Book 声明的构造方法!
得到对象后访问get方法:《程序猿植发》
class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-
我是class="token class -name">Book 声明的构造方法!
《程序猿植发》这本书是我的伙伴!
class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-- class="token operator">-
class="token class -name">class="token namespace">comclass="token punctuation">. junitclass="token punctuation">. democlass="token punctuation">. Book
三、详解:
对于任何一个类,都能知道这个类所有的属性和方法;对于任何一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的class ="tags" href="/tags/FanShe.html" title=反射>反射机制。
getMethod()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
getDeclaredMethod()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
详细举例:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token class -name">Class aClass class="token operator">= class="token class -name">Class class="token punctuation">. class="token function">forName class="token punctuation">( class="token string">"com.junit.demo.Book" class="token punctuation">) class="token punctuation">;
1、访问静态方法:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token comment">// 由Class获取方法:第一个参数为方法名,第二个参数为方法的参数类型。
class="token comment">// 如add(int a,int b)则getMethod("add",int.class ,int.class )。当然,也可以是Java对象。
class="token class -name">Method method class="token operator">= aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"printProduceDate" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
class="token comment">// 引用方法:(引用实例/调用静态方法可为null,参数值/有多个用逗号隔开),参数值要和参数类型的数量匹配!
class="token class -name">String result class="token operator">= class="token punctuation">( class="token class -name">String class="token punctuation">) methodclass="token punctuation">. class="token function">invoke class="token punctuation">( aClassclass="token punctuation">, class="token string">"《程序猿的颈椎自传》" class="token punctuation">) class="token punctuation">;
简写:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"printProduceDate" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">. class="token function">invoke class="token punctuation">( class="token keyword">null class="token punctuation">, class="token string">"《程序猿的颈椎自传》" class="token punctuation">) class="token punctuation">;
2、访问实例方法:
重要:aClass.newInstance();
,实例化指定对象。 和 new Book() 效果一样。
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token comment">//方法一:直接转化实例化后的对象,直接调用方法
class="token class -name">Book bookclass="token operator">= class="token punctuation">( class="token class -name">Book class="token punctuation">) aClassclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token comment">// book.setName('xxx'); or book.getName(); or more...
class="token comment">//方法二:使用invoke调用指定实例a的指定方法b
class="token class -name">Method method3 class="token operator">= aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"toString" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
class="token comment">//这里的book可以是已实例化的对象,或者使用 aClass.newInstance() 传入,详见简写:
class="token class -name">String result3 class="token operator">= class="token punctuation">( class="token class -name">String class="token punctuation">) method3class="token punctuation">. class="token function">invoke class="token punctuation">( bookclass="token punctuation">, class="token string">"这本书是我的伙伴!" class="token punctuation">) class="token punctuation">;
简写:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">aClassclass="token punctuation">. class="token function">getMethod class="token punctuation">( class="token string">"toString" class="token punctuation">, class="token class -name">String class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">. class="token function">invoke class="token punctuation">( aClassclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token punctuation">) class="token punctuation">, class="token string">"xxx" class="token punctuation">) class="token punctuation">;
值得注意的是,如果是类似于工具类可用于全部类访问的,可以使用一个实例化对象,而不需要每次都newInstance。
另外,方法一适用于需要映射的类是已知或少数时,反之需要统一按指定字符串class ="tags" href="/tags/FanShe.html" title=反射>反射调用方法的话,需使用方法二。
3、访问私有方法:
一睹为快:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">
举例:
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package class="token namespace">comclass="token punctuation">. junitclass="token punctuation">. demo class="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">Netbar class="token punctuation">{
class="token keyword">private class="token class -name">Double random class="token operator">= class="token class -name">Math class="token punctuation">. class="token function">random class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token keyword">public class="token class -name">Double class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">{
class="token keyword">return randomclass="token punctuation">;
class="token punctuation">}
class="token keyword">private class="token class -name">Netbar class="token function">createNew class="token punctuation">( class="token punctuation">) class="token punctuation">{
class="token keyword">return class="token keyword">new class="token class -name">Netbar class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token keyword">private class="token keyword">static class="token class -name">Netbar class="token function">getInstance class="token punctuation">( class="token punctuation">) class="token punctuation">{
class="token keyword">return class="token keyword">new class="token class -name">Netbar class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token keyword">public class="token keyword">static class="token keyword">void class="token function">main class="token punctuation">( class="token class -name">String class="token punctuation">[ class="token punctuation">] argsclass="token punctuation">) class="token punctuation">{
class="token class -name">Netbar netbar class="token operator">= class="token keyword">new class="token class -name">Netbar class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"Random:: " class="token operator">+ netbarclass="token punctuation">. class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token class -name">Netbar netbar2 class="token operator">= netbarclass="token punctuation">. class="token function">createNew class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"Random2:: " class="token operator">+ netbar2class="token punctuation">. class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token class -name">Netbar netbar3 class="token operator">= class="token class -name">Netbar class="token punctuation">. class="token function">getInstance class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"Random3:: " class="token operator">+ netbar3class="token punctuation">. class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token punctuation">}
结果为打印的3个值都是不同的,这是正常的访问方式,下面用class ="tags" href="/tags/FanShe.html" title=反射>反射来访问。
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">public class="token keyword">static class="token keyword">void class="token function">main class="token punctuation">( class="token class -name">String class="token punctuation">[ class="token punctuation">] argsclass="token punctuation">) class="token keyword">throws class="token class -name">Exception class="token punctuation">{
class="token class -name">Class aClass class="token operator">= class="token class -name">Class class="token punctuation">. class="token function">forName class="token punctuation">( class="token string">"com.junit.demo.Netbar" class="token punctuation">) class="token punctuation">;
class="token class -name">Method method class="token operator">= aClassclass="token punctuation">. class="token function">getDeclaredMethod class="token punctuation">( class="token string">"createNew" class="token punctuation">) class="token punctuation">; class="token comment">//这里可以带参数
methodclass="token punctuation">. class="token function">setAccessible class="token punctuation">( class="token boolean">true class="token punctuation">) class="token punctuation">; class="token comment">//对所有属性设置访问权限 当类中的成员变量为private时 必须设置此项
class="token class -name">Netbar netbar class="token operator">= class="token punctuation">( class="token class -name">Netbar class="token punctuation">) methodclass="token punctuation">. class="token function">invoke class="token punctuation">( aClassclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"Random2:: " class="token operator">+ netbarclass="token punctuation">. class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">public class="token keyword">static class="token keyword">void class="token function">main class="token punctuation">( class="token class -name">String class="token punctuation">[ class="token punctuation">] argsclass="token punctuation">) class="token keyword">throws class="token class -name">Exception class="token punctuation">{
class="token class -name">Class aClass class="token operator">= class="token class -name">Class class="token punctuation">. class="token function">forName class="token punctuation">( class="token string">"com.junit.demo.Netbar" class="token punctuation">) class="token punctuation">;
class="token class -name">Method method class="token operator">= aClassclass="token punctuation">. class="token function">getDeclaredMethod class="token punctuation">( class="token string">"getInstance" class="token punctuation">) class="token punctuation">; class="token comment">//这里可以带参数
methodclass="token punctuation">. class="token function">setAccessible class="token punctuation">( class="token boolean">true class="token punctuation">) class="token punctuation">; class="token comment">//对所有属性设置访问权限 当类中的成员变量为private时 必须设置此项
class="token class -name">Netbar netbar class="token operator">= class="token punctuation">( class="token class -name">Netbar class="token punctuation">) methodclass="token punctuation">. class="token function">invoke class="token punctuation">( class="token keyword">null class="token punctuation">) class="token punctuation">;
class="token class -name">System class="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"Random2:: " class="token operator">+ netbarclass="token punctuation">. class="token function">getRandom class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
end.