文档章节

Java - 反射

KuangCaibao
 KuangCaibao
发布于 2015/04/18 14:38
字数 667
阅读 124
收藏 1

意义:

目前还不知道,只是觉得这种思想很酷。


实例:

package test;

class Demo {
    public Demo() {
        // TODO Auto-generated constructor stub
        System.out.println("Demo construct");
    }
	
    public void Print() {
        System.out.println("Demo Print");
    }
}

public class JavaReflet {
	
    public static void main(String[] args) {	
        Class<?> cls = null;
        
        try {
            cls = Class.forName("test.Demo");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    		
        Demo demo = null;
        try {
            demo = (Demo)cls.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    		
        demo.Print();		
        System.out.println(cls.getName());
    }
}

// output
Demo construct
Demo Print
test.Demo

注意:

1. Demo类中的构造函数很重要,必须实现

如果没有 public Demo() {} 函数,那么在  cls.newInstance(); 这个方法中会报错

java.lang.InstantiationException: test.Demo
	at java.lang.Class.newInstance(Class.java:418)
	at tdx.ClassReflect.main(ClassReflect.java:30)

从这里可以看到,通过反射建立类的实例,只能使用无参数的构造函数来构造类,这也是和 New 来建立类实例的一个很大的区别。

2. Class.forName(String className, boolean initailize, ClassLoader classLoader )

Java中的一个类如何被加载到JVM中,首先这个Java类应该先被编译成 .class 文件,这样被类加载器ClassLoader加载到JVM中,连接,实例。可见一般的过程: 编译(Compile) -> 装入(Load) -> 连接(Link) -> 实例(Initialize)。Class.forName 的第2个参数的作用就是确定类的class文件被装入到JVM中,是否直接实例化。第3个参数很好理解,就是使用哪个类加载器。

Class.forName("package.className")  == Class.forName("packageName", true, this.getClass().getClassLoader())   默认为加载当前类的加载器。

这里就有一个问题了,如果调用  Class.forName("package.className");   按接口文档的意思,应该这个调用的类已经实例化了,为什么还要调用  newInstance() 方法???

Creates a new instance of the class represented by this Class object. The class is instantiated as if by a new expression with an empty argument list. The class is initialized if it has not already been initialized.

这是 newInstance() 函数的说明,如果类没有被实例化,函数就实例化这个类???


2015 - 04 - 29

回到上面的 initialized 的问题,先看个示例

package test;

class Ref {
	
	static {
		System.out.println("Ref static code");
	}
	
	public static void Print() {
		System.out.println("Ref static method");
	}
	
	public Ref() {

		System.out.println("Ref constructor");
	}
}

public class ReflectTest {

	public static void main(String[] args) {
		
		Class<?> cls = null;
		
		try {
			cls = Class.forName("test.Ref", true, Thread.currentThread().getContextClassLoader());
//			cls = Class.forName("test.Ref", false, Thread.currentThread().getContextClassLoader());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
//		Ref ref = null;
//		try {
//			ref = (Ref) cls.newInstance();
//		} catch (InstantiationException | IllegalAccessException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
}

Ref 类有 静态代码,静态方法和构造函数。如果我们的initialized参数为true,那么执行 forName 操作后,我们Ref类中的 静态代码 部分就执行了,这里的输出

// output
Ref static code

如果 initialized 参数值为 false,如果我们不调用 newInstance 方法,那么没有任何的输出。这时执行 newInstance 操作后,输出

// output
Ref static code
Ref construtor
Ref construtor  // 如果你再实例化另一个Ref实例的话


© 著作权归作者所有

KuangCaibao
粉丝 2
博文 21
码字总数 10699
作品 0
武汉
程序员
私信 提问
【免费】全网独家:详解Java反射机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/silencezwm/article/details/85115991 【免费】全网独家:这是一份非常值得珍藏的Android知识体系!!! 本文...

silencezwm
2018/12/20
0
0
最最最常见的Java面试题总结——第二周

String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性   String类中使用字符数组:保存字符串,所以String对象是...

Amsour丶
2018/08/13
0
0
老司机带你深入浅出Java反射

反射,它就像是一种魔法,引入运行时自省能力,赋予了 Java 语言令人意外的活力,通过运行时操作元数据或对象,Java 可以灵活地操作运行时才能确定的信息 这里笔者就深入浅出总结下Java反射,...

小刀爱编程
2018/11/07
141
0
云妹总结了一些最最最常见的Java面试题供大家参考

云妹导读:String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性 String类中使用字符数组:private final cha...

阿里云科技快讯
2018/08/17
0
0
Android 4.4(KK)中利用APP打开关闭数据流量

在Android 4.4中,在app中打开或关闭数据流量 如果有这方面需求可以参考。 思路 利用JAVA的反射机制(Reflection),来调用CONNECTIVITY_SERVICE完成相关操作。 关于JAVA的反射机制,可以参考...

W_X
2014/12/17
762
4

没有更多内容

加载失败,请刷新页面

加载更多

LeetCode 第 287 号问题:寻找重复数,一道非常简单的数组遍历题,加上四个条件后感觉无从下手

今天分享的题目来源于 LeetCode 第 287 号问题:寻找重复数。 题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只...

五分钟学算法
30分钟前
3
0
vuex mapActions

本文转载于:专业的前端网站➧vuex mapActions 在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在...

前端老手
31分钟前
3
0
使用bash -x 调试信息查看lvextend -r的调用

--1.打开调试: [root@db01 storage]# set -x --2.执行命令: [root@db01 storage]# /usr/sbin/lvextend -r -L 710M /dev/shazam/storage + /usr/sbin/lvextend -r -L 710M /dev/shazam/sto......

突突突酱
40分钟前
3
0
Linux重定向及反弹shell详解

这里说Linux重定向的原因主要还是为了详细了解一下Linux中的反弹shell 目录 0x01 文件描述符 0x02 重定向 0x03 反弹shell 0x04 交互重定向 0x05 命令变形 0x01 文件描述符 Linux的文件描述符...

无心的梦呓
45分钟前
3
0
开发经验 初学51单片机建议用C语言

typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   新手学习51单片机建议用C语言。因为使用C语言入门的话,上手速度快。实现几个例程后...

志成就
51分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部