Java动态加载类
详见:https://blog.csdn.net/zai_xia/article/details/80026325
扩展:java反射机制与动态加载类 https://www.cnblogs.com/wzk-0000/p/9322866.html
在讲解动态加载类之前呢,我们先弄清楚为什么要动态加载类,静态加载不行吗?我们可以看下面的实例:
我在文件夹里写了Office.java 类和 Word.java类,如下:
Office.java
class Office{
public static void main(String[] args){
if(args[0].equals("Word")){
Word w = new Word();
w.start();
}
if(args[0].equals("Excel")){
Excel e = new Excel();
e.start();
}
}
Word.java
class Word{
public void start(){
System.out.println("Word Start");
}
编译会报错,这当然没问题,因为确实没有写Excel.java类。
但是这个Excel类我们一定会用到吗?如果这个Excel类需要很久才能写出来,在此我们也不能使用其他功能吗?后面如果一个类出问题了,这个系统是不是就瘫痪了?
所以这就体现出动态加载类的好处了,动态加载类是按需加载的,你需要什么类,就加载什么类,一个类的状态,不会影响到另一个类的使用。
所以我们可以将Office类改造如下:
class Office{
public static void main(String[] args){
try{
Class c = Class.forName(args[0]);
Word w = (Word)c.newInstance();
w.start();
}
catch(Exception e){
e.printStackTrace();
}
}
虽然我们还是没有写Excel类,但此时我们再编译Office.java文件,编译通过;
成功按照我们预想的结果运行,这样Word类就可以单独运行。
但是这样还是不够规范,因为现在只能加载Word类类型的类文件,为了使程序有更好的扩展性,我们添加一个接口,只有让所有的功能类实现该接口即可。完善如下:
OfficeAble.java
interface OfficeAble{
public void start();
}
Office.java
class Office{
public static void main(String[] args){
try{
Class c = Class.forName(args[0]);
OfficeAble oa = (OfficeAble)c.newInstance();
oa.start();
}
catch(Exception e){
e.printStackTrace();
}
}
Word.java
class Word implements OfficeAble{
public void start(){
System.out.println("Word Start");
}
}
这样改造之后,我后面要添加一个Excel类,乃至添加其他的类,只需要实现OfficeAble接口就可以了,不需要改动Office这个类和其他的功能类,扩展性很强,这就是动态加载的优势。
扩展:java的反射机制与动态加载
什么是java反射机制?
1、当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射。
IT行业里这么说,没有反射也就没有框架,现有的框架都是以反射为基础。在实际项目开发中,用的最多的是框架,填的最多的是类,反射这一概念就是将框架和类揉在一起的调和剂。所以,反射才是接触项目开发的敲门砖。
2、java中的new方法是静态加载,因为new方法是在编译阶段就会检查,而不是在运行阶段。反射是可以在运行时创建对象,调用对象的方法、变量等。
3、Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
例如:
package service.impl;
public class Test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
F f = new F();
// 第一种表达方式
Class c1 = F.class;// 这种表达方式同时也告诉了我们任何一个类都有一个隐含的静态成员变量class
// 第二种表达方式
Class c2 = f.getClass();// 这种表达方式在已知了该类的对象的情况下通过getClass方法获取
// 第三种表达方式
Class c3 = Class.forName("service.impl.F");// 类的全称
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
F temp = (F) c1.newInstance();//这里可以是c1/c2/c3
System.out.println(temp.f);
temp.save();
}
}
class F {
public String f = "test";
public void save() {
System.out.println("save...");
}
}
运行结果
service.impl.F
service.impl.F
service.impl.F
test
save...
动态加载 。。。。
如果没有不带参数的构造函数,则不能通过c1.newInstance() 构造对象,需要先获取构造函数,再构造对象
Class c = Class.forName("com.my.app.Book");
Constructor con = c.getConstructor(String.class);
Book book = (Book) con.newInstance("语文");
System.out.println(book);
4.获取方法,运行方法:
package com.my.app;
public class Book {
private String name ="金1瓶1梅";
public Book() {
super();
}
public Book(String name) {
super();
this.name = name;
}
public void outDate(){
System.out.println("1111111 ");
}
public void outDate(String string){
System.out.println("1111111 " +string);
}
public void outDate(String string,int num){
System.out.println("1111111 " +string +" " +num);
}
}
Class c = Class.forName("com.my.app.Book");
Book book = (Book) c.newInstance();
book.outDate();
Method[] methods = c.getMethods();
Method method = c.getMethod("outDate", String.class,int.class);
method.invoke(book, "6465465",55);
Method method = c.getMethod("outDate", String.class);
method.invoke(book, "6465465");
获取变量
Class c = Class.forName("com.my.app.Book");
Book book = (Book) c.newInstance();
Field field1 = c.getField("price");//根据变量名,返回一个具体的具有public属性的成员变量
Field field2 = c.getDeclaredField("price");//根据变量名,返回一个成员变量(不分public和非public属性)
System.out.println(field1.getDouble(book));
System.out.println(field2.getName());//获取变量名
System.out.println(field2.getType());//获取变量类型
System.out.println(field2.get(book));//获取变量值
System.out.println(field2.getDouble(book));//获取变量值
//获取私有字段 模拟get set方法
Field nameField = c.getDeclaredField("name");
//取消访问私有字段的合法性检查
nameField.setAccessible(true);
System.out.println(nameField.get(book));
nameField.set(book, "BBBB");
System.out.println(book);
Java动态加载类的更多相关文章
- java动态加载类和静态加载类笔记
JAVA中的静态加载类是编译时刻加载类 动态加载类指的是运行时刻加载类 二者有什么区别呢 举一个例子 现在我创建了一个类 实现的功能假设为通过传入的参数调用具体的类和方法 class offic ...
- Java动态加载类在功能模块开发中的作用
Java中我们一般会使用new关键字实例化对象然后调用该对象所属类提供的方法来实现相应的功能,比如我们现在有个主类叫Web类这个类中能实现各种方法,比如用户注册.发送邮件等功能,代码如下: /* * ...
- java reflect 初始学习 动态加载类
首先要理解Class类: 在java 的反射中,Class.forName("com.lilin.Office") 使用类的全名,这样获取,不仅仅表示了类的类类型,同时还代表着类的 ...
- Java运行时动态加载类之ClassLoader
https://blog.csdn.net/fjssharpsword/article/details/64922083 *************************************** ...
- java反射机制与动态加载类
什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...
- Java 反射理解(二)-- 动态加载类
Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编 ...
- java反射动态加载类Class.forName();
1,所有的new出来的对象都是静态加载的,在程序编译的时候就会进行加载.而使用反射机制Class.forName是动态加载的,在运行时刻进行加载. 例子:直接上两个例子 public class Ca ...
- 关于实现Extjs动态加载类的方式实现
Extjs4以前的版本没有动态加载类的方式,这样开发程序的时候加载很多的js会导致加载变慢,由于本人一直使用extjs3的版本进行开发,于是简单实现了一个动态加载类的管理器,使用方式与extjs4的方 ...
- tomcat 5.5 动态加载类
转载于:http://www.itxuexiwang.com/a/javadianzishu/tomcat/2016/0225/161.html?1456480735 开发使用的是tomcat5.5. ...
随机推荐
- 2018-2019-2 网络对抗技术 20165232 Exp 8 Web基础
2018-2019-2 网络对抗技术 20165232 Exp 8 Web基础 原理与实践说明 1.实践内容概述 Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与 ...
- Postman下载与安装
融e学-一个专注于重构知识,培养复合型人才的平台:http://www.i-ronge.com/ Postman 的官网下载地址是:https://www.getpostman.com/ 下载后看到压 ...
- leetcode-easy-string- 125 Valid Palindrome
mycode 9.62% class Solution(object): def isPalindrome(self, s): """ :type s: str :r ...
- ajaxGird修改一条记录中的字段
var rowData = ajaxgrid.getSelectedRow(); var quality = rowData["quality"]; var rowIndex = ...
- 使用django-cors-headers 来解决跨域问题
在settting里面这样配置 ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ 'django. ...
- python - readline 模块
转载:https://www.cnblogs.com/fireflow/p/4841413.html readline模块定义了一系列函数用来读写Python解释器中历史命令,并提供自动补全命令功能. ...
- mysql中文乱码 常见编码问题解决方法分享
我是真的服了 mysql默认字符不是utf-8也不是GBK而是拉丁文字?? 在增删数据时 “中文字符” 老是乱码不停!害得我浪费不少时间在这上面 为各位之后不走坑 再此留下解决方法 若想进一步了解编码 ...
- 前端必须掌握的 nginx 技能(4)
概述 作为一个前端,我觉得必须要学会使用 nginx 干下面几件事: 代理静态资源 设置反向代理(添加https) 设置缓存 设置 log 部署 smtp 服务 设置 redis 缓存(选) 下面我按 ...
- Ubuntu基础设定:openssh-server安装和使用
记录一下Ubuntu17.10的openssh-server的安装和使用.安装之后就可以使用ssh登陆Ubuntu了,所以是Ubuntu的基础设定之一. 事前准备 Ubuntu版本:17.10 dev ...
- Day05:循环问题 / 数组
循环嵌套 循环结构中包含完整的循环结构. 注意: 循环嵌套不限层次 各种循环语句都可以互相嵌套 内层循环中出现的break和continue只作用在内层循环中 外层循环循环一次 内层循环循环一遍 Ja ...