java-反射
来源:互联网 发布:大拿韩代 淘宝 编辑:程序博客网 时间:2024/06/07 00:10
package xq.com.cn;/** * Created by lenovo on 2017/7/4. */public class ClassDemos { /** * 构造函数 */ public ClassDemos() { System.out.println("构造方法:classDemo!"); } public static void main(String[] args) throws Exception { /** * Class.forName(String):要求JVM查找并加载String指定的类 * 返回String字符串指定的类 */ Class clazz = Class.forName("xq.com.cn.ClassDemos"); System.out.println("forName==" + clazz);//class xq.com.cn.ClassDemos /** * clazz.newInstance() * 返回的类所代表的一个实例和new ClassDemo()效果是一样的。 */ ClassDemos classDemo = (ClassDemos) clazz.newInstance(); System.out.println("newInstance==" + classDemo);//xq.com.cn.ClassDemos@1540e19d }}
打印结果:
forName==class xq.com.cn.ClassDemos构造方法:classDemo!newInstance==xq.com.cn.ClassDemos@1540e19d
可见:
Class.forName(“”)返回的是类
Class.forName(“”).newInstance()返回的是类的对象
// 以下为一样的效果。 A a = (A)Class.forName("pacage.A").newInstance(); A a = new A();
从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个 类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。
newInstance()和new的区别:
首先,newInstance( )是一个方法,而new是一个关键字,
其次,Class下的newInstance()的使用有局限,因为它生成对象只能调用无参的构造函数,而使用 new关键字生成对象没有这个限制。
newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
forName()方法
这个方法总是返回要加载的类的Class类的实例
1、forName(String className)单参数时, initialize=true
a.总是使用当前类装载器(也就是装载执行forName()请求的类 的类装载器)
b.总是初始化这个被装载的类(当然也包括:装载、连接、初始化)
2、forName(String className, boolean initialize, ClassLoader loader)
a.loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。
b.initialize=true时,肯定连接,而且初始化了;
c.false时,绝对不会初始化,但是可能被连接了,但是这里有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,这里也暗含着:被同一个loader所装载的,而且这个类被初始化了)
关于用户自定义的类装载器的loadClass()方法
1、loadClass(String name)单参数时, resolve=false
a.如果这个类已经被这个类装载器所装载,那么,返回这个已经被装载的类型的Class的实例,否则,就用这个自定义的类装载器来装载这个class,这时不知道是否被连接。绝对不会被初始化
b.这时唯一可以保证的是,这个类被装载了。但是不知道这个类是不是被连接和初始化了
2、loadClass(String name, boolean resolve)
a.resolve=true时,则保证已经装载,而且已经连接了。resolve=falses时,则仅仅是去装载这个类,不关心是否连接了,所以此时可能被连接了,也可能没有被连接
参考: 关于Class.forName(className).newInstance()介绍
反射的使用:
写一个简单的类:
package xq.com.cn;/** * Created by lenovo on 2017/7/4. */public class Simple { private void displayMessage(String strMsg) {//注意方法私有Private System.out.println("message is:" + strMsg); }}
测试类:
import xq.com.cn.Simple;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * Created by lenovo on 2017/7/4. */public class Test { public static void main(String[] args) { /*获取类的方法一: 通过类直接获取*/ Class<Simple> simpleClass1 = Simple.class; System.out.println("class111==" + simpleClass1);//直接获取类 /*获取类的方法二: 通过对象获取*/ Simple simple = new Simple(); Class<? extends Simple> aClass = simple.getClass();//通过对象获取类 System.out.println("class222===" + aClass); try { /*获取类的方法三: 通过反射获取*/ Class simpleClass = Class.forName("xq.com.cn.Simple");//通过反射获取类 System.out.println("class333===" + simpleClass); Object simpelObject = simpleClass.newInstance();//获取类的实例 System.out.println("object===" + simpelObject); Class[] args1 = new Class[1]; args1[0] = String.class; //获取类的方法,参数为:方法名,参数类型 Method simpleMethod = simpleClass.getDeclaredMethod("displayMessage", args1); //类中的方法为private,故必须进行此操作, //如果变量为private则变量需要调用此方法才可访问 simpleMethod.setAccessible(true); String[] argments = new String[1]; argments[0] = "Hello,world"; //方法的调用,参数为:对象,参数 simpleMethod.invoke(simpelObject, argments); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } }}
打印结果
class111==class xq.com.cn.Simpleclass222===class xq.com.cn.Simpleclass333===class xq.com.cn.Simpleobject===xq.com.cn.Simple@1540e19dmessage is:Hello,world
getDeclaredMethod与getMethod 区别:
getDeclaredMethod() 获取的是类自身声明的所有方法,包含public、protected和private方法。
getMethod () 获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。
public Method getDeclaredMethod(String name, Class<?>... parameterTypes){ ...}
java.lang.Class.getDeclaredMethod()方法返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法。
name 参数是一个字符串,指定所需的方法的简单名称,即方法名。
parameterTypes 参数是一个数组的Class对象识别方法的形参类型,在声明的顺序。
参考:
java.lang.Class.getDeclaredMethod()方法详解
JAVA 反射-getDeclaredMethod()实例
反射中getMethods 与 getDeclaredMethods 的区别
- 【反射】JAVA反射机制
- JAVA 反射
- java 反射
- Java反射
- java反射
- java反射
- JAVA反射
- java 反射
- Java 反射
- java 反射
- Java反射
- java反射
- JAVA 反射
- java 反射
- Java反射
- java反射
- java 反射
- java 反射
- Android获取系统信息---获取CPU数
- 华为校招上机编程之““字符串的分割””
- 热更新 AndFixDemo
- 禁止from disk cache,禁止浏览器缓存问题
- android 公共顶部栏
- java-反射
- android studio Fetching documentation 函数提示框
- 设计模式(01) 单例模式(创建类模式)(上,两种推荐的实现方法)
- LNMP(linux+nginx+mysql+php)环境的编译安装
- 文件上传中的常见问题
- 将富文本转化为纯文字,新闻更多,只显示一部分新闻详情的时候使用
- PAT (Advanced Level) Practise 1086 Tree Traversals Again (25)
- 算法中常见的数组问题
- 学习 Kotlin 的 20 个实用资源