java 反射,类的加载过程以及Classloader类加载器
首先自定义一个类Person
package reflection; public class Person { private String name;
public int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
} public Person(String name) {
super();
this.name = name;
}
public void show() {
System.out.println("我是一个人");
}
private String showNation(String nation){
System.out.println("我的国籍是"+nation);
return nation;
}
}
然后是反射的一些操作
package reflection; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties; import org.junit.jupiter.api.Test; public class ReflectionTest { @Test
public void test1() throws Exception {
Person p1 = new Person("Tom",12); //1.通过反射,创建Person类的对象
Class clazz = Person.class;
Constructor cons = clazz.getDeclaredConstructor(String.class,int.class); Object obj = cons.newInstance("Tom",12);
Person p = (Person)obj;
System.out.println(p.toString()); //2.通过反射,调用对象指定的属性
Field age = clazz.getDeclaredField("age");
age.set(p, 10);
System.out.println(p.toString()); //3.通过反射,调用方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(p); System.out.println("**********************************************************");
} /*
* 反射调用私有方法和属性
* */
@Test
public void test2() throws Exception{
try {
//通过反射调用私有的方法和属性
Class clazz = Person.class;
//1.调用私有构造器
Constructor cons1 = clazz.getDeclaredConstructor(String.class);
cons1.setAccessible(true);
Person person = (Person)cons1.newInstance("zsben");
System.out.println(person); //2.调用私有属性
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(person, "Lilei");
System.out.println(person); //3.调用私有方法
Method showNation = clazz.getDeclaredMethod("showNation",String.class);
showNation.setAccessible(true);
showNation.invoke(person, "中国"); //4.获得私有方法的返回值
String string = (String)showNation.invoke(person, "中国");
System.out.println(string);
} catch (Exception e) { e.printStackTrace();
}
} /* 关于Class类的理解
* 1.类的加载过程:使用java.exe命令对某个字节码文件进行解释运行,
* 相当于将某个字节码文件加载到内存中,称为类的加载,加载到内存中的类,称其为运行时类
* 此运行时类就作为Class的一个实例
* 2.Class的实例对应着一个运行时类
* 3.加载到内存中的运行时类,会缓存一定的时间之内,我们可以通过不同的方式获取此运行时类
*
* */
/*
* 获取Class实例的四种方式
* */
@Test
public void test3() throws ClassNotFoundException {
//方式1:调用运行时类的属性;Class后面不加泛型也可以
Class<Person> clazz1 = Person.class;
System.out.println(clazz1); //方法2:通过运行时类的对象
Person p1 = new Person();
Class clazz2 = p1.getClass();
System.out.println(clazz2); //方式3:调用Class静态方法forName(String classpath),classpath为类所在路径
Class clazz3 = Class.forName("reflection.Person");
System.out.println(clazz3); //方式4.使用类的加载器
ClassLoader classLoader = ReflectionTest.class.getClassLoader();
classLoader.loadClass("reflection.Person");
Class clazz4 = classLoader.loadClass("reflection.Person"); System.out.println(clazz1==clazz2);
System.out.println(clazz1==clazz3);
System.out.println(clazz1==clazz4);
} }
类加载器的理解
package reflection; import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties; import org.junit.jupiter.api.Test;
/*
* 类的加载过程:
* 1.类的加载:将类的class文件读入内存,并为之创建Class对象,此过程由类加载器完成
* 2.类的链接:将类的二进制数据合并到JRE中,设置static变量的默认值(0,null,""等)
* 3.类的初始化:JVM负责初始化,按顺序执行执行静态代码块和类属性的赋值
*
* */ /*
* 了解类的加载器
*
* */ public class ClassLoaderTest {
@Test
public void test1() {
//对于自定义类,得到ClassLoaderTest的类加载器:属于System Classloader,即系统类加载器
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader); //调用系统类加载器的getParent().得到Extension Classloader,即扩展类加载器
ClassLoader classLoader2 = classLoader.getParent();
System.out.println(classLoader2); //Bootstap Classloader负责加载java核心类库,得不到了
ClassLoader classLoader3 = classLoader2.getParent();
System.out.println(classLoader3); //和3同理,String是java核心类库的
ClassLoader classLoader4 = String.class.getClassLoader();
System.out.println(classLoader4);
} //读取读取配置文件
@Test
public void test4() throws Exception {
//方式1
Properties pros = new Properties();
FileInputStream fis = new FileInputStream("jdbc.properties");
pros.load(fis); String user = pros.getProperty("user");
String passwd = pros.getProperty("password");
System.out.println(user+passwd); } }
通过反射创建运行时类的对象
package reflection; import org.junit.jupiter.api.Test; /*
* 通过反射创建对应的运行时类的对象
* */ public class NewInstanceTest { @Test
public void test1() throws InstantiationException, IllegalAccessException {//实例化异常, 权限异常
Class<Person> clazz = Person.class;
Object object = clazz.newInstance();
System.out.println(object); /*
* newInstance()创建对应的运行时 类的对象
* 内部调用了空参数构造器
* */ Person person = clazz.newInstance();//这儿直接能得到person类运行时类对象
System.out.println(person);
} @Test
public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String classPath = "";
classPath = "java.util.Date";
System.out.println(getInstance(classPath));
classPath = "reflection.Person";
System.out.println(getInstance(classPath));
}
//此方法创建一个指定全类名的实例
public Object getInstance(String classPath) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName(classPath);
return clazz.newInstance();
}
}
java 反射,类的加载过程以及Classloader类加载器的更多相关文章
- Java类的加载过程与ClassLoader的理解及测试
当程序准备运行某个类,但该类还未被加载到内存中时,会经过以下三个步骤进行类的加载: 类的加载(Load)→类的连接(Link)→类的初始化(Initialize) 加载:类经过javac.exe编译的 ...
- Java类的加载过程-重点!!
java类的加载过程有以下几步共同完成: 加载->连接->初始化.连接又分为验证.准备.解析 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以 ...
- JAVA - 类的加载过程
JAVA - 类的加载过程 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象 ...
- Dubbo源码解析之SPI(一):扩展类的加载过程
Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...
- 第42天学习打卡(Class类 Class类的常用方法 内存分析 类的加载过程 类加载器 反射操作泛型 反射操作注解)
Class类 对象照镜子后得到的信息:某个类的属性.方法和构造器.某个类到底实现了哪些接口.对于每个类而言,JRE都为其保留一个不变的Class类型的对象.一个Class对象包含了特定某个结构(cla ...
- JVM——类的加载过程
附一张图方便理解,一个类的执行过程 类的加载过程,简明的来说 类装饰器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件.在Java中,类装载器把一个类装入JVM中,要经过以下步骤: 装载:查 ...
- java类的加载过程
1.类的加载顺序 (1)JVM在首次加载类时会对 静态初始化块.静态成员变量. 静态方法进行一次初始化. (2)只有在调用new方法时才会创建类的实例. (3)对象创建过程: 首先执行父类(如果有) ...
- Java 类的加载过程(阿里面试题)
问以下程序打印出什么内容: 问题及解析如下: /** * 加载方法不等于执行方法,初始化变量则会赋值 * 类加载顺序应为 加载静态方法-初始化静态变量-执行静态代码块 * 实例化时 先加载非静态方法- ...
- 【Spring源码分析系列】启动component-scan类扫描加载过程
原文地址:http://blog.csdn.net/xieyuooo/article/details/9089441/ 在spring 3.0以上大家都一般会配置一个Servelet,如下所示: &l ...
随机推荐
- linux使用apache发布静态html网页
环境 centOS7+httpd 安装httpd 安装 #检查是否安装和httpd rpm -qa | grep httpd #如果没安装 yum -y install httpd 启动httpd并验 ...
- Invoke和BeginInvoke的区别(转载)
转自http://www.cnblogs.com/c2303191/articles/826571.html Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线 ...
- Oracle 一条sql插入多条数据
Oracle一次插入多条数据. 表结构: create table aa ( ID NUMBER(11) PRIMARY KEY, NAME VARCHAR2(20) ) 第一种方式: insert ...
- canvas绘制验证码
css样式: <style> body{ text-align: center; } canvas{ background:#ddd; } </style> body中添加标签 ...
- 应用安全-Web安全-越权漏洞整理
login->register GetPhone->GetPasswd GetPwd->GetPassword 遍历https://xx.com/contacts/new?user_ ...
- SPOJ NICEBTRE - Nice Binary Trees(树 先序遍历)
传送门 Description Binary trees can sometimes be very difficult to work with. Fortunately, there is a c ...
- 简单的C++11线程池实现
线程池的C++11简单实现,源代码来自Github上作者progschj,地址为:A simple C++11 Thread Pool implementation,具体博客可以参见Jakob's D ...
- mybatis插件机制及分页插件原理
MyBatis 插件原理与自定义插件: MyBatis 通过提供插件机制,让我们可以根据自己的需要去增强MyBatis 的功能.需要注意的是,如果没有完全理解MyBatis 的运行原理和插件的工作方式 ...
- 自定义ThreadLocal和事务(基于自定义AOP)
参考<架构探险--从零开始写javaweb框架>4.6章节 自定义ThreadLocal package smart; import java.util.Collections; impo ...
- Python入门习题8.羊车门问题
例8. 羊车门问题描述:有3扇关闭的门,一扇后停着汽车,另外两扇门后是山羊,主持人知道每扇门后是什么.参赛者首先选择一扇门.在开启它之前,主持人会从另外两扇门中打开一扇门,露出门后的山羊.此时,允许参 ...