我的编程空间,编程开发者的网络收藏夹
学习永远不晚

浅谈 Java 反射技术

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

浅谈 Java 反射技术

一、什么是反射?

反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

Oracle 官方对反射的解释是:

Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions. The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。

二、反射的主要用途

很多人都认为反射在实际的 Java 开发应用中并不广泛,其实不然。当我们在使用 IDE(如 Eclipse,IDEA)时,当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。

反射最重要的用途就是开发各种通用框架。很多框架(比如 Spring)都是配置化的(比如通过 XML 文件配置 Bean),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射,运行时动态加载需要加载的对象。

举一个例子,在运用 Struts 2 框架的开发中我们一般会在 struts.xml 里去配置 Action,比如:

  1. <action name="login" 
  2.        class="org.xxx.SimpleLoginAction" 
  3.        method="execute"
  4.    /shop/shop-index.jsp 
  5.    name="error">login.jsp 
  6. action

 

配置文件与Action建立了一种映射关系,当 View层发出请求时,请求会被 StrutsPrepareAndExecuteFilter 拦截,然后 StrutsPrepareAndExecuteFilter 会去动态地创建 Action 实例。比如我们请求 login.action,那么 StrutsPrepareAndExecuteFilter就会去解析struts.xml文件,检索action中name为login的Action,并根据class属性创建SimpleLoginAction实例,并用invoke方法来调用execute方法,这个过程离不开反射。

对与框架开发人员来说,反射虽小但作用非常大,它是各种容器实现的核心。而对于一般的开发者来说,不深入框架开发则用反射用的就会少一点,不过了解一下框架的底层机制有助于丰富自己的编程思想,也是很有益的。

三、反射的基本运用

3.1、通过反射获取class对象

通过反射获取对象有三种方式

3.1.1、Class.forName()获取

  1. public static Class forName(String className) 
  2.             throws ClassNotFoundException { 
  3.     Class caller = Reflection.getCallerClass(); 
  4.     return forName0(className, true, ClassLoader.getClassLoader(caller), caller); 

比如,在 JDBC 开发中常用此方法加载数据库驱动

  1. Class.forName("包名.类名"); 

3.1.2、类名.class获取

例如:

  1. Class intClass = int.class; 
  2. Class integerClass = Integer.TYPE; 
  3.  
  4. #RelfectEntity类为本文的例子 
  5. Class relfectEntity2 = RelfectEntity.class; 

3.1.3、对象getClass()获取

  1. StringBuilder str = new StringBuilder("123"); 
  2.  
  3. Class strClass = str.getClass(); 

三种方法都可以实现获取class对象,框架开发中,一般第一种用的比较多。

3.2、获取类的构造器信息

获取类构造器的用法,主要是通过Class类的getConstructor方法得到Constructor类的一个实例,而Constructor类有一个newInstance方法可以创建一个对象实例:

  1. public T newInstance(Object ... initargs) 

3.3、获取类的实例

通过反射来生成对象主要有两种方式。

使用Class对象的newInstance()方法来创建Class对象对应类的实例。

  1. Class c = String.class; 
  2.  
  3. Object str = c.newInstance(); 

先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。

  1. //获取String所对应的Class对象 
  2. Class c = String.class; 
  3. //获取String类带一个String参数的构造器 
  4. Constructor constructor = c.getConstructor(String.class); 
  5. //根据构造器创建实例 
  6. Object obj = constructor.newInstance("23333"); 
  7. System.out.println(obj); 

这种方法可以用指定的构造器构造类的实例。

3.4、获取类的变量

实体类:

  1.  
  2. public class BaseClass { 
  3.  
  4.     public String publicBaseVar1; 
  5.  
  6.     public String publicBaseVar2; 
  7.  
  8.  
  9. public class ChildClass extends BaseClass{ 
  10.  
  11.     public String publicOneVar1; 
  12.  
  13.     public String publicOneVar2; 
  14.  
  15.     private String privateOneVar1; 
  16.  
  17.     private String privateOneVar2; 
  18.  
  19.     public String printOneMsg() { 
  20.         return privateOneVar1; 
  21.     } 

测试:

  1. public class VarTest { 
  2.      
  3.     public static void main(String[] args) { 
  4.         //1.获取并输出类的名称 
  5.         Class mClass = ChildClass.class; 
  6.         System.out.println("类的名称:" + mClass.getName()); 
  7.         System.out.println("----获取所有 public 访问权限的变量(包括本类声明的和从父类继承的)----"); 
  8.          
  9.         //2.获取所有 public 访问权限的变量(包括本类声明的和从父类继承的) 
  10.         Field[] fields = mClass.getFields(); 
  11.          
  12.         //遍历变量并输出变量信息 
  13.         for (Field field : fields) { 
  14.             //获取访问权限并输出 
  15.             int modifiers = field.getModifiers(); 
  16.             System.out.print(Modifier.toString(modifiers) + " "); 
  17.              
  18.             //输出变量的类型及变量名 
  19.             System.out.println(field.getType().getName() + " " + field.getName()); 
  20.         } 
  21.         System.out.println("----获取所有本类声明的变量----"); 
  22.          
  23.         //3.获取所有本类声明的变量 
  24.         Field[] allFields = mClass.getDeclaredFields(); 
  25.         for (Field field : allFields) { 
  26.             //获取访问权限并输出 
  27.             int modifiers = field.getModifiers(); 
  28.             System.out.print(Modifier.toString(modifiers) + " "); 
  29.              
  30.             //输出变量的类型及变量名 
  31.             System.out.println(field.getType().getName() + " " + field.getName()); 
  32.         } 
  33.     } 

输出结果:

  1. 类的名称:com.example.java.reflect.ChildClass 
  2. ----获取所有 public 访问权限的变量(包括本类声明的和从父类继承的)---- 
  3. public java.lang.String publicOneVar1 
  4. public java.lang.String publicOneVar2 
  5. public java.lang.String publicBaseVar1 
  6. public java.lang.String publicBaseVar2 
  7. ----获取所有本类声明的变量---- 
  8. public java.lang.String publicOneVar1 
  9. public java.lang.String publicOneVar2 
  10. private java.lang.String privateOneVar1 
  11. private java.lang.String privateOneVar2 

3.5、修改类的变量

修改子类

  1.  
  2. public class ChildClass extends BaseClass{ 
  3.  
  4.     public String publicOneVar1; 
  5.  
  6.     public String publicOneVar2; 
  7.  
  8.     private String privateOneVar1; 
  9.  
  10.     private String privateOneVar2; 
  11.  
  12.     public String printOneMsg() { 
  13.         return privateOneVar1; 
  14.     } 

测试:

  1. public class VarModfiyTest { 
  2.      
  3.     public static void main(String[] args) throws Exception { 
  4.         //1.获取并输出类的名称 
  5.         Class mClass = ChildClass.class; 
  6.         System.out.println("类的名称:" + mClass.getName()); 
  7.         System.out.println("----获取ChildClass类中的privateOneVar1私有变量----"); 
  8.          
  9.         //2.获取ChildClass类中的privateOneVar1私有变量 
  10.         Field privateField = mClass.getDeclaredField("privateOneVar1"); 
  11.          
  12.         //3. 操作私有变量 
  13.         if (privateField != null) { 
  14.             //获取私有变量的访问权 
  15.             privateField.setAccessible(true); 
  16.              
  17.             //实例化对象 
  18.             ChildClass obj = (ChildClass) mClass.newInstance(); 
  19.              
  20.             //修改私有变量,并输出以测试 
  21.             System.out.println("privateOneVar1变量,修改前值: " + obj.printOneMsg()); 
  22.  
  23.             //调用 set(object , value) 修改变量的值 
  24.             //privateField 是获取到的私有变量 
  25.             //obj 要操作的对象 
  26.             //"hello world" 为要修改成的值 
  27.             privateField.set(obj, "hello world"); 
  28.             System.out.println("privateOneVar1变量,修改后值: " + obj.printOneMsg()); 
  29.         } 
  30.     } 

输出结果:

  1. 类的名称:com.example.java.reflect.ChildClass 
  2. ----获取ChildClass类中的privateOneVar1私有变量---- 
  3. privateOneVar1变量,修改前值: null 
  4. privateOneVar1变量,修改后值:hello world 

3.6、获取类的所有方法

修改实体类

  1.  
  2. public class BaseClass { 
  3.  
  4.     public String publicBaseVar1; 
  5.  
  6.     public String publicBaseVar2; 
  7.  
  8.     private void privatePrintBaseMsg(String var) { 
  9.         System.out.println("基类-私有方法,变量:" + var); 
  10.     } 
  11.  
  12.     public void publicPrintBaseMsg(String var) { 
  13.         System.out.println("基类-公共方法,变量:" + var); 
  14.     } 
  15.  
  16.  
  17. public class ChildClass extends BaseClass{ 
  18.  
  19.     public String publicOneVar1; 
  20.  
  21.     public String publicOneVar2; 
  22.  
  23.     private String privateOneVar1; 
  24.  
  25.     private String privateOneVar2; 
  26.  
  27.     public String printOneMsg() { 
  28.         return privateOneVar1; 
  29.     } 
  30.  
  31.     private void privatePrintOneMsg(String var) { 
  32.         System.out.println("子类-私有方法,变量:" + var); 
  33.     } 
  34.  
  35.     public void publicPrintOneMsg(String var) { 
  36.         System.out.println("子类-公共方法,变量:" + var); 
  37.     } 

测试:

  1. public class MethodTest { 
  2.  
  3.     public static void main(String[] args) { 
  4.         //1.获取并输出类的名称 
  5.         Class mClass = ChildClass.class; 
  6.         System.out.println("类的名称:" + mClass.getName()); 
  7.         System.out.println("----获取所有 public 访问权限的方法,包括自己声明和从父类继承的---"); 
  8.  
  9.         //2 获取所有 public 访问权限的方法,包括自己声明和从父类继承的 
  10.         Method[] mMethods = mClass.getMethods(); 
  11.         for (Method method : mMethods) { 
  12.             //获取并输出方法的访问权限(Modifiers:修饰符) 
  13.             int modifiers = method.getModifiers(); 
  14.             System.out.print(Modifier.toString(modifiers) + " "); 
  15.  
  16.             //获取并输出方法的返回值类型 
  17.             Class returnType = method.getReturnType(); 
  18.             System.out.print(returnType.getName() + " " + method.getName() + "( "); 
  19.  
  20.             //获取并输出方法的所有参数 
  21.             Parameter[] parameters = method.getParameters(); 
  22.             for (Parameter parameter : parameters) { 
  23.                 System.out.print(parameter.getType().getName() + " " + parameter.getName() + ","); 
  24.             } 
  25.  
  26.             //获取并输出方法抛出的异常 
  27.             Class[] exceptionTypes = method.getExceptionTypes(); 
  28.             if (exceptionTypes.length == 0){ 
  29.                 System.out.println(" )"); 
  30.             } else { 
  31.                 for (Class c : exceptionTypes) { 
  32.                     System.out.println(" ) throws " + c.getName()); 
  33.                 } 
  34.             } 
  35.         } 
  36.         System.out.println("----获取所有本类的的方法---"); 
  37.         //3. 获取所有本类的的方法 
  38.         Method[] allMethods = mClass.getDeclaredMethods(); 
  39.         for (Method method : allMethods) { 
  40.             //获取并输出方法的访问权限(Modifiers:修饰符) 
  41.             int modifiers = method.getModifiers(); 
  42.             System.out.print(Modifier.toString(modifiers) + " "); 
  43.  
  44.             //获取并输出方法的返回值类型 
  45.             Class returnType = method.getReturnType(); 
  46.             System.out.print(returnType.getName() + " " + method.getName() + "( "); 
  47.  
  48.             //获取并输出方法的所有参数 
  49.             Parameter[] parameters = method.getParameters(); 
  50.             for (Parameter parameter : parameters) { 
  51.                 System.out.print(parameter.getType().getName() + " " + parameter.getName() + ","); 
  52.             } 
  53.  
  54.             //获取并输出方法抛出的异常 
  55.             Class[] exceptionTypes = method.getExceptionTypes(); 
  56.             if (exceptionTypes.length == 0){ 
  57.                 System.out.println(" )"); 
  58.             } else { 
  59.                 for (Class c : exceptionTypes) { 
  60.                     System.out.println(" ) throws " + c.getName()); 
  61.                 } 
  62.             } 
  63.         } 
  64.     } 

输出:

  1. 类的名称:com.example.java.reflect.ChildClass 
  2. ----获取所有 public 访问权限的方法,包括自己声明和从父类继承的--- 
  3. public java.lang.String printOneMsg(  ) 
  4. public void publicPrintOneMsg( java.lang.String arg0, ) 
  5. public void publicPrintBaseMsg( java.lang.String arg0, ) 
  6. public final void wait( long arg0,int arg1, ) throws java.lang.InterruptedException 
  7. public final native void wait( long arg0, ) throws java.lang.InterruptedException 
  8. public final void wait(  ) throws java.lang.InterruptedException 
  9. public boolean equals( java.lang.Object arg0, ) 
  10. public java.lang.String toString(  ) 
  11. public native int hashCode(  ) 
  12. public final native java.lang.Class getClass(  ) 
  13. public final native void notify(  ) 
  14. public final native void notifyAll(  ) 
  15. ----获取所有本类的的方法--- 
  16. public java.lang.String printOneMsg(  ) 
  17. private void privatePrintOneMsg( java.lang.String arg0, ) 
  18. public void publicPrintOneMsg( java.lang.String arg0, ) 

为啥会输出这么多呢?

因为所有的类默认继承object类,打开object类会发现有些公共的方法,所以一并打印出来了!

3.7、调用方法

  1. public class MethodInvokeTest { 
  2.  
  3.     public static void main(String[] args) throws Exception { 
  4.         // 1.获取并输出类的名称 
  5.         Class mClass = ChildClass.class; 
  6.         System.out.println("类的名称:" + mClass.getName()); 
  7.         System.out.println("----获取ChildClass类的私有方法privatePrintOneMsg---"); 
  8.  
  9.         // 2. 获取对应的私有方法 
  10.         // 第一个参数为要获取的私有方法的名称 
  11.         // 第二个为要获取方法的参数的类型,参数为 Class...,没有参数就是null 
  12.         // 方法参数也可这么写 :new Class[]{String.class} 
  13.         Method privateMethod = mClass.getDeclaredMethod("privatePrintOneMsg", String.class); 
  14.  
  15.         // 3. 开始操作方法 
  16.         if (privateMethod != null) { 
  17.             // 获取私有方法的访问权 
  18.             // 只是获取访问权,并不是修改实际权限 
  19.             privateMethod.setAccessible(true); 
  20.  
  21.             // 实例化对象 
  22.             ChildClass obj = (ChildClass) mClass.newInstance(); 
  23.  
  24.             // 使用 invoke 反射调用私有方法 
  25.             // obj 要操作的对象 
  26.             // 后面参数传实参 
  27.             privateMethod.invoke(obj, "hello world"); 
  28.         } 
  29.     } 

输出结果:

  1. 类的名称:com.example.java.reflect.ChildClass 
  2.  
  3. ----获取ChildClass类的私有方法privatePrintOneMsg--- 
  4.  
  5. 子类-私有方法,变量:hello world 

四、总结

由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

五、参考文章

sczyh30:深入解析Java反射

伯特:Java 反射由浅入深

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

浅谈 Java 反射技术

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

浅谈 Java 反射技术

反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

浅谈无人机侦测反制技术

无人机发展起步于军事领域,上世纪90年代以后,在军事应用上取得了突飞猛进的发展。

Java反射技术怎么用

这篇文章主要为大家展示了“Java反射技术怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java反射技术怎么用”这篇文章吧。一、基本反射技术1.1 根据一个字符串得到一个类getClass
2023-06-25

如何理解Java反射技术

本篇内容介绍了“如何理解Java反射技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前期概要1、 什么是反射Java 反射机制在程序运
2023-06-02

java的反射技术详细介绍

本篇内容主要讲解“java的反射技术详细介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java的反射技术详细介绍”吧!反射的定义:审查元数据并收集关于它的类型信息的能力。下面介绍java的反
2023-06-17

java反射技术的使用场景

这篇文章主要介绍“java反射技术的使用场景”,在日常操作中,相信很多人在java反射技术的使用场景问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java反射技术的使用场景”的疑惑有所帮助!接下来,请跟着小编
2023-06-03

浅谈网络爬虫技术与反爬虫防护

网络爬虫按照实现的技术和结构可以分为以下几种类型:通用网络爬虫、聚焦网络爬虫、增量式网络爬虫、深层网络爬虫等。在实际的网络爬虫中,通常是这几类爬虫的组合体。

如何在Java中应用反射技术

如何在Java中应用反射技术?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、反射概念Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象
2023-06-15

五分钟技术趣谈 | 浅谈Docker

随着互联网的极速发展,应用程序的功能越来越丰富,而需要迭代的速度要求也越来越高,为实现这些目标,应用的开发逐渐趋向服务化甚至微服务化。每个应用程序都有其对应依赖的操作系统或者其他程序,而在将应用程序细分为不同的微服务或者是其他形式的微小应用
Docker开源2024-11-30

浅谈java反射和自定义注解的综合应用实例

前言前几天学习了反射和自定义注解,刚好工作中遇到一个小问题:前台传递到后台的必填字段为空,导致不能插入数据库。就是这样一个小问题,让我考虑到是否可以做一个通用的方法,让前台传递过来的必填字段在后台也校验一遍,如果传递为空,则把响应字段返回提
2023-05-31

浅谈网络爬虫技术

目前网络上存在着海量的数据资料,将这些数据爬取保存下来,并进行进一步操作,即可挖掘出数据的潜在价值。如今的互联网存在的缺陷是用户很难获得有用的数据资料,虽然传统的搜索引擎可以为用户返回大量信息,但是用户需要在庞杂的数据中寻找对自己有用的

浅谈VMWARE云原生技术栈

除了灾备之外它还能做资源移转,支持把容器应用从一个集群迁移到另一个集群。Velero是一个云原生的灾难恢复和迁移工具,它本身也是开源的, 采用Go语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷。

五分钟技术趣谈 | 浅谈微前端

前端即网站前台部分,运行在PC端,移动端等浏览器上展现给用户浏览的网页。随着互联网技术的发展,HTML5,CSS3,前端框架的应用,跨平台响应式网页设计能够适应各种屏幕分辨率,合适的动效设计,给用户带来极高的用户体验。随着时间的推移,前端往
微前端2024-11-30

浅谈Linux的零拷贝技术

前言 在linux系统内部缓存和内存容量都是有限的,更多的数据都是存储在磁盘中。对于Web服务器来说,经常需要从磁盘中读取数据到内存,然后再通过网卡传输给用户:那么这也算一次I O的过程,都知道IO过程中需要状态的切换还有一系列拷贝过程,都
2023-04-28

深入浅析java中反射的原理

深入浅析java中反射的原理?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.Class类任何一个类都是Class的实例对象,这个实例对象有三种表示方式//第一种表示方式---
2023-05-31

浅谈 Java 中的反序列化漏洞!

随着 Json 数据交换格式的普及,直接应用在服务端的反序列化接口也随之减少,但陆续爆出的Jackson和Fastjson两大 Json 处理库的反序列化漏洞,也暴露出了一些问题。

五分钟技术趣谈 | 浅谈GPU虚拟化

GPU虚拟化是一种技术,它允许多个虚拟环境共享单个物理GPU的资源,它能带来提高资源利用率、降低成本、高灵活性和可扩展性、提高安全性等方面的好处。随着GPU在各种领域的应用越来越普及,如图形渲染、通用计算(如深度学习)、音视频编解码等,GP

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录