java反射机制概念:Java反射机制是指在程序运行时,通过分析类的字节码来获取类的信息,并在运行时动态地创建对象、调用方法、访问属性等。它允许程序在运行时借助于Reflection API取得任何已知名称的class的内部信息,包括类名、修饰符、变量、构造函数、方法、父类、接口等。
通过反射机制,我们可以在运行时获取类的信息,而不需要在编译时知道该类的名字。这使得我们可以动态地创建对象,调用方法和访问属性,从而提高了代码的灵活性和可重用性。具体来说,反射机制提供了以下功能:
-
获取类的完整结构:可以获取类的名称、成员变量、构造函数、方法、注解等信息。
-
动态创建对象:可以通过类的Class对象的newInstance()方法动态地创建一个对象实例。
-
动态调用方法:可以通过Method对象动态地调用类的方法。
-
动态访问属性:可以通过Field对象动态地访问类的成员变量。
java反射机制的优缺点
优点:
- 实现动态创建对象和编译代码,增强了程序的灵活性和可扩展性;
- 可以在运行时获取类的信息并访问私有成员,方便进行调试和测试;
- 可以实现框架和插件化开发,例如Spring框架就大量使用了反射机制。
缺点:
- 反射操作需要额外的资源消耗,包括内存和CPU等,降低了程序的性能;
- 反射操作不易于调试和维护,错误难以定位和排查;
- 反射操作容易破坏程序的封装性和安全性,因为它可以访问私有成员和调用私有方法。
因此,在使用反射机制时需要权衡其优缺点,确保在需要灵活性和可扩展性的情况下才使用反射,避免过度依赖反射机制导致程序性能下降和安全问题。
下面是一个关于java反射机制的案例:
创建一个名为Person的类:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
通过反射机制获取“Person”类的实例,并调用其“getName”方法。代码如下:
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// 获取Person类的Class对象
Class<?> clazz = Class.forName("Person");
// 创建Person类的实例
Object person = clazz.getConstructor(String.class).newInstance("John");
// 获取getName方法
Method method = clazz.getMethod("getName");
// 调用getName方法并输出结果
String name = (String) method.invoke(person);
System.out.println("Name: " + name);
}
}
进阶版,使用java的反射原理解决java代码更改需要重新编译并重启服务器的问题
1.分层结构
2.创建接口和实现类
dao包
接口:
package com.liu.dao;
public interface BookDao {
void fun();
}
实现类:
package com.liu.dao;
public class BookDaoImpl implements BookDao{
@Override
public void fun() {
System.out.println("BookDao ...fun");
}
}
service包
接口:
package com.liu.service;
public interface BookService {
void fun();
}
实现类:
//声明一个名为com.liu.servlet的包
package com.liu.servlet;
//导入BookService接口和BookServiceImpl、BookServiceVip实现类
import com.liu.service.BookService;
import com.liu.service.Impl.BookServiceImpl;
import com.liu.service.Impl.BookServiceVip;
//定义一个名为BookServlet的类,实现BookService接口
public class BookServlet implements BookService {
//重写BookService接口中的fun方法
@Override
public void fun() {
//创建BookServiceImpl和BookServiceVip的实例对象
BookService bookService = new BookServiceImpl();
BookService bookService1 = new BookServiceVip();
//在控制台打印信息
System.out.println("BookServlet ....fun");
}
}
//声明一个名为com.liu.service.Impl的包
package com.liu.service.Impl;
//导入BookDao接口和BookDaoImpl实现类以及BookService接口
import com.liu.dao.BookDao;
import com.liu.dao.BookDaoImpl;
import com.liu.service.BookService;
//定义一个名为BookServiceVip的类,实现BookService接口
public class BookServiceVip implements BookService {
//重写BookService接口中的fun方法
@Override
public void fun() {
//创建BookDaoImpl实例对象
BookDao bookDao =new BookDaoImpl();
//调用BookDaoImpl中的fun方法
bookDao.fun();
//在控制台打印信息
System.out.println("BookServiceVip.... fun");
}
}
servlet包
//声明一个名为com.liu.servlet的包
package com.liu.servlet;
//导入BookService接口和BookServiceImpl、BookServiceVip实现类
import com.liu.service.BookService;
import com.liu.service.Impl.BookServiceImpl;
import com.liu.service.Impl.BookServiceVip;
//定义一个名为BookServlet的类,实现BookService接口
public class BookServlet implements BookService {
//重写BookService接口中的fun方法
@Override
public void fun() {
//创建BookServiceImpl和BookServiceVip的实例对象
BookService bookService = new BookServiceImpl();
BookService bookService1 = new BookServiceVip();
//在控制台打印信息
System.out.println("BookServlet ....fun");
}
}
//声明一个名为com.liu.servlet的包
package com.liu.servlet;
//导入BookService接口、InputStream类、Properties类、Class类、Constructor类以及异常类Exception
import com.liu.service.BookService;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;
//定义一个名为Test01的主类
public class Test01 {
public static void main(String[] args) throws Exception {
//获取info.properties文件的输入流
InputStream stream = Test01.class.getClassLoader().getResourceAsStream("info.properties");
//创建一个Properties实例对象,并加载输入流
Properties p = new Properties();
p.load(stream);
//根据key获取value
String classname = p.getProperty("className");
//根据类的全路径名获取Class对象
Class cla = Class.forName(classname);
//获取无参构造方法的Constructor对象
Constructor constructor = cla.getDeclaredConstructor();
//通过反射创建实例对象
BookService bookService = (BookService) constructor.newInstance();
//调用实例对象中的fun方法
bookService.fun();
}
}
properties文件:
className=com.liu.service.Impl.BookServiceImpl
用于决定执行impl还是Vip
运行结果: