Java SE:反射超详解(二)

简介: Java SE:反射超详解(二)

5.3 获取某个类的类加载器对象

通过这个类的CLass对象.getCLassLoader()

代码演示如下:

public class TestMain {
    public static void main(String[] args) throws ClassNotFoundException {
        //引导区的类加载器
        Class c1= Class.forName("java.lang.String");
        ClassLoader classLoader = c1.getClassLoader();
        System.out.println("Str类的类加载器:"+classLoader);//Str类的类加载器:null
        //why?引导区的类加载器不是由Java语言实现的,所以得不到它的对象,故而为null
        //应用程序类加载器
        Class c2= Class.forName("exercise.e10.TestMain");
        ClassLoader loader = c2.getClassLoader();
        System.out.println(loader);//sun.misc.Launcher$AppClassLoader@18b4aac2 应用程序类加载器
        //扩展类加载器
        Class c3=Class.forName("sun.security.pkcs11.Config");
        System.out.println(c3.getClassLoader());//sun.misc.Launcher$ExtClassLoader@54bedef2
    }
}


六. 反射的基本应用

🤮注意:

特别用cLass.forName(“类型的全名称”)获取class对象时

若被打jar包的模块中发生代码的增删修改,比如新建一个类或成员变量或方法。一定要及时build Artifacts–>build 自己打好的jar包,然后把新build的jar包及时替换到jdk–>jre–>lib-ext目录下

6.1 获取类型的详细信息

🚩只要可以获取一个类的CLass对象,就可以获取它里面的所有的信息。

代码演示如下:

@Test
    public void test01() throws ClassNotFoundException {
        Class c1=Class.forName("java.lang.String");
        //1)获取String类的class对象的包名
        System.out.println(c1.getPackage());
        //2)获取class对象的类名
        System.out.println(c1.getName());
        //3)获取类的修饰符
        int modifiers = c1.getModifiers();
        System.out.println(modifiers);//17
        System.out.println(Modifier.toString(modifiers));
        //4)获取类的父类
        System.out.println(c1.getSuperclass());
        //5)获取类的实现的接口
        System.out.println(c1.getName()+"实现的接口:");
        Class[] interfaces = c1.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface);
        }
        //6)获取String类的成员变量
        /*
        获取string类所有成员变量
        clazz.getField("属性名");   获取某一个公共的成员变量
        clazz.getFields();          获取所有的公共的成员变量
        clazz.getDeclaredField("属性名"); 获取某一个已声明的成员变量
        clazz.getDeclaredFields();   获取所有已声明的成员变量,包括非公共的,私有的等
*/
        System.out.println("String类的所有成员变量:");
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //7)获取String类的构造方法
        //获取string类的构造器们
/*      clazz.getConstructor(构造器的形参类型列表)  获取一个公共的构造器
        clazz.getConstructors(); 获取所有公共的构造器
        clazz.getDeclaredConstructor(构造器的形参类型列表) 获取一个已声明的构造器
        clazz.getDeclaredConstructors();  获取所有已声明的构造器
        */
        System.out.println(c1.getName()+"所有的构造器:");
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        //8)获取String类的方法们
        //获取string类的方法们
        /*
        cLazz.getMethod(方法名, 方法的形参类型列表): 获取某个公共的方法
        clazz.getDeclaredMethod(方法名,方法的形参类型列表): 获取某个已声明的方法
        clazz.getMethods() 获取所有公共的方法
        clazz.getDeclaredMethods() 获取所有已声明的方法 */
        System.out.println(c1.getName()+"所有的方法们:");
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("-------------------------------------------");
        Class c2= ArrayList.class;
        //9)获取ArrayList的子类们
        System.out.println(c2.getName()+"所有的内部类们:");
        Class[] declaredClasses = c2.getDeclaredClasses();
        for (Class innerClass : declaredClasses) {
            System.out.println(innerClass);
        }
    }

6.2 创建任意类型的对象

🚩当然不包括 基本数据类型和void,抽象类,接口等

6.2.1 方案一

步骤:

(1) 先获取这个类的CLass对象

(2) 调用CLass对象的newInstance()方法来创建实例对象

🔔注意:

这种方式创建对象有限制,必须要求这个类有无参的公共构造器

代码演示如下:

@Test
public void test02() throws Exception {
    Class<?> c1 = Class.forName("testPackage.TestMain");
    Object obj = c1.newInstance();
    System.out.println(obj);//java.lang.ClassNotFoundException: testPackage.TestMain
    //原因:另一个模块outerModule的testPackage.TestMain没有导入到本模块demo的train.t1 的扩展类加载器中
}

🚩如何导出为jar包?

请看如下演示:

1)单击工具栏的图标,如下所示:

然后打开项目设置

2)选择Artifacts(打包部署),选择添加jar。

3)给导出的jar命名,确认导出的路径

4)确认创建或选择已有的Manifest.MF文件。单词“manifest”的意思是“显示” 。 这个 manifest 文件定义了与扩展和包相关的数据。

🌏 说明:

打开Java的JAR文件,我们经常可以看到文件中包含着一个META-INF目录,这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息 。

5)选择Manifest.MF文件存储目录。

6)选择jar要包含的.class文件的目录,即要打包的模块的out目录

7)编译生成jar

💡小tips:

编译好的jar包在哪里?

在第三步中创建jar包时指定的jar包存储路径里去找

8)把编译好的jar包复制,粘贴到jdk安装目录下 jre–>lib–>ext 下

💡小tips:

这样就可以通过扩展类加载器去找另一个模块下的类的clss对象

代码演示如下:

public class t1 {
    public static void main(String[] args) throws Exception{
        Class<?> c1 = Class.forName("testP1.testMain");
        Object obj = c1.newInstance();//这个obj对象实际上是模块Testmodule下的testP1.testMain类的对象
        System.out.println(obj);
    }
}

代码演示如下:

Class c2=Class.forName("testP1.testDemo");
Object o = c2.newInstance();//这个obj对象实际上是模块Testmodule下的testP1.testDemo类的对象
System.out.println(o);
/*
Exception in thread "main" java.lang.InstantiationException: testP1.testDemo
Caused by: java.lang.NoSuchMethodException: testP1.testDemo.<init>()
模块Testmodule下的testP1.testDemo类没有无参构造
*/

相关文章
|
22小时前
|
Java C++
Java反射的简单使用
Java反射的简单使用
21 3
|
22小时前
|
Java
【专栏】Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性
【4月更文挑战第27天】本文探讨了Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性。反射通过Class、Constructor、Method和Field类实现。文中列举了反射的应用场景,如动态创建对象、调用方法、访问属性和处理注解,并提供了相关实例代码演示。
|
22小时前
|
Java 开发框架 XML
JDK、JRE、Java SE、Java EE和Java ME有什么区别?
JDK、JRE、Java SE、Java EE和Java ME有什么区别?
|
22小时前
|
SQL 存储 Java
【Java反射详解】
【Java反射详解】
11 1
|
22小时前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
【5月更文挑战第2天】JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
40 2
|
22小时前
|
Java 索引
Java SE ____二维数组
Java SE ____二维数组
|
22小时前
|
Java 测试技术
滚雪球学Java(24):Java反射
【4月更文挑战第13天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 0
滚雪球学Java(24):Java反射
|
22小时前
|
Java
Java 反射
Java 反射
|
22小时前
|
设计模式 Java 索引
由反射引出的Java动态代理与静态代理
由反射引出的Java动态代理与静态代理
15 0
|
22小时前
|
存储 Java Shell
深入剖析Java中的反射,由浅入深,层层剥离!
深入剖析Java中的反射,由浅入深,层层剥离!
14 1