网站首页 > 精选教程 正文
正常的反射实例化一个类很容易,但是当涉及内部类的情况就有点不一样了。本文关于内部类的语法是最核心的部分,更多内容可参考语法书。 本文所有的异常都用Exception,不会区分何种异常。具体情况要根据实际情况。
Test001代码
Test001.java代码如下,在其中包含一个私有的内部类,其构造函数是带有参数的。
package java_code;
public class Test001 {
public Test001(){
System.out.println("burning");
}
private class Test001001 {
public Test001001(String str){
System.out.println(str);
}
}
public class Test001002 {
public Test001002(){
System.out.println("burning002");
}
}
static class Test001003 {
public Test001003(){
System.out.println("burning003");
}
}
private static class Test001004 {
public Test001004(){
System.out.println("burning004");
}
}
}
外部类实例化
公用类的反射实例化: 下面的代码给出了两种方式,不过第一种方式是Deprecated的。
try{
//Class.forName("java_code.Test001").newInstance();
Test001.class.getDeclaredConstructor().newInstance();
} catch (Exception e){
e.printStackTrace();
}
内部类的实例化
内部类的出现是简化了Java那,还是把Java搞复杂了那。笔者更倾向于后者,可能也是我对Java的理解不够。尤其是匿名内部类和lambda表达式的出现,虽然能够在一定程度上减少代码量,但是极大的增加了代码的阅读难度。
内部类
内部类分为如下三种:
1.静态类2.非静态类3.局部内部类,具体可参考lambda表达式
内部类的共有4个作用域: 同一个类、同一个包、父子类和任意位置。
静态内部类
静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类只是持有外部类的类引用,没有持有外部类对象的引用,这也就是为什么静态内部类的实例方法不能外部类的实例属性的原因。
非静态内部类
在非静态内部类的对象里,保存了一个它所寄生的外部类的对象引用,所以可以访问外部类的私有成员。
反射
有了反射,Java的灵活性上升了一个层级,不过安全性就. . .
在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。
Android中的很多hook技术,利用的就是反射+代理来实现的,后面的文章会专门写Android的hook机制,包括Binder的HOOK。
API
没有什么比官方文档更权威的解释,如果有,那就是源代码了。相应的API均来自官方文档。
Modifier and TypeMethodDescriptionCommentClass<?>[]getDeclaredClasses()Returns an array of Class objects reflecting all the classes and interfaces declared as members of the class represented by this Class object.获取到所有的类,包括内部类和接口。ConstructorgetConstructor?(Class<?>... parameterTypes)Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.如果是非静态内部类的话,第一个参数需要是其寄生的外部类Constructor<?>[]getConstructors?()Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.当实在搞不明白参数该怎么传的时候,可以考虑把所有的构造器都打印出来TnewInstance?(Object... initargs)Uses the constructor represented by this Constructor object to create and initialize a new instance of the constructor's declaring class, with the specified initialization parameters.如果是非静态内部类的话,第一个参数需要是其寄生的外部类实例
实例化私有内部类
Test.java代码如下,关键地方给出了注释。
package java_code;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
Test001 test001 = new Test001();
Object object = getInnerInstance(test001);
try{
Class.forName("java_code.Test001").newInstance();
//Test001.class.getDeclaredConstructor().newInstance();
} catch (Exception e){
e.printStackTrace();
}
}
private static Object getInnerInstance(Test001 test001) {
Object object = null;
try {
Class[] innnerClass = test001.getClass().getDeclaredClasses();
for (Class c: innnerClass){
if (c.getName().indexOf("Test001001") != -1){//有参数
//Constructor cc = c.getConstructors()[0];
Constructor cc = c.getConstructor(test001.getClass(), String.class);
object = cc.newInstance(test001, "欢迎关注我的微信公众号:无情剑客");
} else if (c.getName().indexOf("Test001002") != -1){//无参数
Constructor cc = c.getConstructor(test001.getClass());
object = cc.newInstance(test001);
} else {//静态内部类
Constructor cc = c.getConstructor();
object = cc.newInstance();
}
}
return object;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
最终运行结果:
参考
https://docs.oracle.com/javase/9/javadoc/javadoc.html
写在最后
网上很多写反射的,但是对于内部类的反射涉及的非常少,尤其是这种私有的内部类。也许有人认为私有内部类是不能被外部实例化的,但是强大的反射功能突破了Java本身的一些规则。
公众号
更多内容,欢迎关注我的微信公众号:无情剑客。
- 上一篇: Java 的各种内部类、Lambda表达式
- 下一篇: 「java」浅谈java内部类
猜你喜欢
- 2024-11-24 永远不要使用双花括号初始化实例,除非你想OOM
- 2024-11-24 java中的匿名内部类总结
- 2024-11-24 Java Nested Classes(内部类~英文技术文档翻译)
- 2024-11-24 带你深入学习java内部类_匿名类,细到不能再细
- 2024-11-24 为何要在Java中使用静态类?
- 2024-11-24 68、下面的内部类在哪里new不会编译出错
- 2024-11-24 面向对象高级特性内部类
- 2024-11-24 Java局部内部类
- 2024-11-24 Java 内部类和异常类(详细版)
- 2024-11-24 IntelliJ IDEA 2022.2.1 beta 发布,新增支持 Java 18
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)