昨天在群里跟大家讨论了下java反射调用可变参数的问题,这个问题起因是我们需要反射调用另一个部门提供的方法,我同事说java不能反射调用可变参数的方法,于是我写了个demo证明了他这个观点的错误。但是测试过程中,有一点我不明白,就是反射调用可变参数的方法时,为什么一定要保证传入的参数数组长度为1,在群里跟大家讨论了很多,没有得到确切的答案,参照网上大牛写的东西和我自己跟源码的过程,记录如下:

  1.两个类,一个父类,一个子类

  [java] view plain copy print?

  package com.reflect.test;

  public class BaseObject {

  public void getObjectName(){

  System.out.println("BaseObject");

  }

  }

  [java] view plain copy print?

  package com.reflect.test;

  public class SubObject extends BaseObject{

  @Override

  public void getObjectName() {

  System.out.println("SubObject");

  }

  public void getParamsLength(String...params){

  System.out.println("param's length is:"+params.length);

  }

  public void getParamsLength(String param1,String param2){

  System.out.println(param1 + "-" + param2);

  }

  }

  2.测试类,主要测试重载方法的调用、可变参数方法的调用、定参方法的调用

  [java] view plain copy print?

  package com.reflect.test;

  import java.lang.reflect.Method;

  public class ReflectTest {

  private static final String BASE_OBJECT_PATH = "com.reflect.test.BaseObject";

  private static final String SUB_OBJECT_PATH = "com.reflect.test.SubObject";

  public static void main(String[] args) throws Exception{

  Class bClazz = Class.forName(BASE_OBJECT_PATH);

  Class sClazz = Class.forName(SUB_OBJECT_PATH);

  Object bObj = bClazz.newInstance();//父类实例

  Object sObj = sClazz.newInstance();//子类实例

  //1.反射调用子类父类的重载方法

  //多态+动态绑定

  Method bMethod = bClazz.getDeclaredMethod("getObjectName");

  bMethod.invoke(bObj);//父类的bMethod调用父类的getObjectName()

  bMethod.invoke(sObj);//父类的bMethod调用子类的getObjectName();

  Method sMethod = sClazz.getDeclaredMethod("getObjectName");

  //不符合多态和动态绑定

  //sMethod.invoke(bObj);//sMethod调用父类的getObjectName(),会报错:java.lang.IllegalArgumentException: object is not an instance of declaring class

  sMethod.invoke(sObj);

  //2.反射调用可变参数的方法

  Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);

  //可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常

  String[] strParams = {"a","b","c"};

  Object[] cParams = {strParams};

  changeMethod.invoke(sObj, cParams);

  //3.反射调用固定长度参数的方法

  Method unChangeMethod1 = sClazz.getDeclaredMethod("getParamsLength", String.class,String.class);

  unChangeMethod1.invoke(sObj, "Hello","Java");

  //也可以写成这样

  Class[] clazzs = {String.class,String.class};

  Method unChangeMethod2 = sClazz.getDeclaredMethod("getParamsLength", clazzs);

  unChangeMethod2.invoke(sObj, "Hello","Java");

  //下面的这种调用形式也是可以的,不过会报警告

  //String[] params1 = {"Hello","Java"};

  //unChangeMethod1.invoke(sObj, params1);

  }

  }

  下面是JDK里面Method 的invoke方法的源码

  从代码中可以看出,先检查 AccessibleObject的override属性是否为true(override属性默认为false)。AccessibleObject是Method,Field,Constructor的父类,可调用setAccessible方法改变,如果设置为true,则表示可以忽略访问权限的限制,直接调用。

  如果不是ture,则要进行访问权限检测。用Reflection的quickCheckMemberAccess方法先检查是不是public的,如果不是再用Reflection.getCallerClass()方法获得到调用这个方法的Class,然后做是否有权限访问的校验,校验之后缓存一次,以便下次如果还是这个类来调用就不用去做校验了,直接用上次的结果。

  [java] view plain copy print?

  @CallerSensitive

  public Object invoke(Object obj, Object... args)

  throws IllegalAccessException, IllegalArgumentException,

  InvocationTargetException

  {

  if (!override) {

  if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {

  // Until there is hotspot @CallerSensitive support

  // can't call Reflection.getCallerClass() here

  // Workaround for now: add a frame getCallerClass to

  // make the caller at stack depth 2

  Class caller = getCallerClass();

  checkAccess(caller, clazz, obj, modifiers);

  }

  }

  MethodAccessor ma = methodAccessor; // read volatile

  if (ma == null) {

  ma = acquireMethodAccessor();

  }

  return ma.invoke(obj, args);

  }

  /验证的代码,securityCheckCache就是JDK做的缓存

  volatile Object securityCheckCache;

  void checkAccess(Class caller, Class clazz, Object obj, int modifiers)

  throws IllegalAccessException

  {

  if (caller == clazz) { // quick check

  return; // ACCESS IS OK

  }

  Object cache = securityCheckCache; // read volatile

  Class targetClass = clazz;

  if (obj != null

  && Modifier.isProtected(modifiers)

  && ((targetClass = obj.getClass()) != clazz)) {

  // Must match a 2-list of { caller, targetClass }.

  if (cache instanceof Class[]) {

  Class[] cache2 = (Class[]) cache;

  if (cache2[1] == targetClass &&

  cache2[0] == caller) {

  return; // ACCESS IS OK

  }

  // (Test cache[1] first since range check for [1]

  // subsumes range check for [0].)

  }

  } else if (cache == caller) {

  // Non-protected case (or obj.class == this.clazz).

  return; // ACCESS IS OK

  }

  // If no return, fall through to the slow path.

  slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);

  }

  然后就是调用MethodAccessor的invoke方法了。

  调用MethodAccessor的invoke方法。每个Method对象包含一个root对象,root对象里持有一个MethodAccessor对象。这个对象由ReflectionFactory方法生成,ReflectionFactory对象在Method类中是static final的由native方法实例化。代码片段如下;

  [java] view plain copy print?

  //Method类中的代码片段,生成MethodAccessor

  private volatile MethodAccessor methodAccessor;

  private Method root;

  private MethodAccessor acquireMethodAccessor() {

  // First check to see if one has been created yet, and take it

  // if so

  MethodAccessor tmp = null;

  if (root != null) tmp = root.getMethodAccessor();

  if (tmp != null) {

  methodAccessor = tmp;

  } else {

  // Otherwise fabricate one and propagate it up to the root

  tmp = reflectionFactory.newMethodAccessor(this);

  setMethodAccessor(tmp);

  }

  return tmp;

  }

  // reflectionFactory在父类AccessibleObject中定义,代码片段如下:

  static final ReflectionFactory reflectionFactory =

  AccessController.doPrivileged(

  new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());

  ReflectionFactory生成MethodAccessor:如果noInflation的属性为true则直接返回MethodAccessorGenerator创建的一个MethodAccessor,否则返回DelegatingMethodAccessorImpl,并将他与一个NativeMethodAccessorImpl互相引用。但DelegatingMethodAccessorImpl执行invoke方法的时候又委托给NativeMethodAccessorImpl了。代码片段如下:

  [java] view plain copy print?

  public MethodAccessor newMethodAccessor(Method paramMethod) {

  checkInitted();

  if (noInflation) {

  return new MethodAccessorGenerator().generateMethod(paramMethod.getDeclaringClass(), paramMethod.getName(), paramMethod.getParameterTypes(), paramMethod.getReturnType(), paramMethod.getExceptionTypes(), paramMethod.getModifiers());

  }

  NativeMethodAccessorImpl localNativeMethodAccessorImpl = new NativeMethodAccessorImpl(paramMethod);

  DelegatingMethodAccessorImpl localDelegatingMethodAccessorImpl = new DelegatingMethodAccessorImpl(localNativeMethodAccessorImpl);

  localNativeMethodAccessorImpl.setParent(localDelegatingMethodAccessorImpl);

  return localDelegatingMethodAccessorImpl;

  }

  MethodAccessor实现有两个版本,一个是Java实现的,另一个是native code实现的。Java实现的版本在初始化时需要较多时间,但长久来说性能较好;native版本正好相反,启动时相对较快,但运行时间长了之后速度就比不过Java版了。这是HotSpot的优化方式带来的性能特性,同时也是许多虚拟机的共同点:跨越native边界会对优化有阻碍作用,它就像个黑箱一样让虚拟机难以分析也将其内联,于是运行时间长了之后反而是托管版本的代码更快些。 为了权衡两个版本的性能,Sun的JDK使用了“inflation”的技巧:让Java方法在被反射调用时,开头若干次使用native版,等反射调用次数超过阈值时则生成一个专用的MethodAccessor实现类,生成其中的invoke()方法的字节码,以后对该Java方法的反射调用就会使用Java版。

  看下NativeMethodAccessorImpl 中的invoke方法:

  代码片段如下:

  [java] view plain copy print?

  package sun.reflect;

  import java.lang.reflect.InvocationTargetException;

  import java.lang.reflect.Method;

  class NativeMethodAccessorImpl extends MethodAccessorImpl

  {

  private Method method;

  private DelegatingMethodAccessorImpl parent;

  private int numInvocations;

  NativeMethodAccessorImpl(Method paramMethod)

  {

  this.method = paramMethod;

  }

  public Object invoke(Object paramObject, Object[] paramArrayOfObject)

  throws IllegalArgumentException, InvocationTargetException

  {

  if (++this.numInvocations > ReflectionFactory.inflationThreshold()) {

  MethodAccessorImpl localMethodAccessorImpl = (MethodAccessorImpl)new MethodAccessorGenerator().generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());

  this.parent.setDelegate(localMethodAccessorImpl);

  }

  return invoke0(this.method, paramObject, paramArrayOfObject);

  }

  void setParent(DelegatingMethodAccessorImpl paramDelegatingMethodAccessorImpl) {

  this.parent = paramDelegatingMethodAccessorImpl;

  }

  private static native Object invoke0(Method paramMethod, Object paramObject, Object[] paramArrayOfObject);

  }

  调用natiave方法invoke0执行方法调用.

  注意这里有一个计数器numInvocations,每调用一次方法+1,当比 ReflectionFactory.inflationThreshold(15)大的时候,用MethodAccessorGenerator创建一个MethodAccessor,并把之前的DelegatingMethodAccessorImpl引用替换为现在新创建的。下一次DelegatingMethodAccessorImpl就不会再交给NativeMethodAccessorImpl执行了,而是交给新生成的java字节码的MethodAccessor

  每次NativeMethodAccessorImpl.invoke()方法被调用时,都会增加一个调用次数计数器,看超过阈值没有;一旦超过,则调用MethodAccessorGenerator.generateMethod()来生成Java版的MethodAccessor的实现类,并且改变DelegatingMethodAccessorImpl所引用的MethodAccessor为Java版。后续经由DelegatingMethodAccessorImpl.invoke()调用到的就是Java版的实现了。

  注意到关键的invoke0()方法是个native方法。它在HotSpot VM里是由JVM_InvokeMethod()函数所支持的,是用C写的

  为了验证这个结论,我故意写出一个非法参数,循环调用16次并catch下异常,结果如下:从结果中看出,前15次都是调用NativeMethodAccessorImpl,第16次开始就是调用DelegatingMethodAccessorImpl了。

  [java] view plain copy print?

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException: wrong number of arguments

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  java.lang.IllegalArgumentException

  at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

  at java.lang.reflect.Method.invoke(Method.java:606)

  at com.reflect.test.ReflectTest.main(ReflectTest.java:44)

  下面看看java版的DelegatingMethodAccessorImpl的实现:

  [java] view plain copy print?

  package sun.reflect;

  import java.lang.reflect.InvocationTargetException;

  class DelegatingMethodAccessorImpl extends MethodAccessorImpl

  {

  private MethodAccessorImpl delegate;

  DelegatingMethodAccessorImpl(MethodAccessorImpl paramMethodAccessorImpl)

  {

  setDelegate(paramMethodAccessorImpl);

  }

  public Object invoke(Object paramObject, Object[] paramArrayOfObject)

  throws IllegalArgumentException, InvocationTargetException

  {

  return this.delegate.invoke(paramObject, paramArrayOfObject);

  }

  void setDelegate(MethodAccessorImpl paramMethodAccessorImpl) {

  this.delegate = paramMethodAccessorImpl;

  }

  package sun.reflect;

  public class GeneratedMethodAccessor1 extends MethodAccessorImpl {

  public GeneratedMethodAccessor1() {

  super();

  }

  public Object invoke(Object obj, Object[] args)

  throws IllegalArgumentException, InvocationTargetException {

  // prepare the target and parameters

  if (obj == null) throw new NullPointerException();

  try {

  A target = (A) obj;

  if (args.length != 1) throw new IllegalArgumentException();

  String arg0 = (String) args[0];

  } catch (ClassCastException e) {

  throw new IllegalArgumentException(e.toString());

  } catch (NullPointerException e) {

  throw new IllegalArgumentException(e.toString());

  }

  // make the invocation

  try {

  target.foo(arg0);

  } catch (Throwable t) {

  throw new InvocationTargetException(t);

  }

  }

  }

  if (args.length != 1) throw new IllegalArgumentException();这一句就能解释我之前的疑问了,这块会判断参数数组的长度,如果长度不等于1,就会抛出非法参数的异常。

  而且MethodAccessor会做强制类型转换再进行方法调用,但父类强制转化成子类的的时候就会报错类型不匹配错误了,所以如果变量的引用声明是父但实际指向的对象是子,那么这种调用也是可以的。美源星

  http://beijing.jinti.com/licai/21943299.htm

  http://beijing.jinti.com/licai/21943339.htm

  http://beijing.jinti.com/licai/21943364.htm

  http://beijing.jinti.com/licai/21943399.htm

  http://beijing.jinti.com/licai/21943429.htm

  http://beijing.jinti.com/licai/21943857.htm

  http://beijing.jinti.com/licai/21944259.htm

  http://beijing.jinti.com/licai/21944297.htm

  http://beijing.jinti.com/licai/21944348.htm

  http://beijing.jinti.com/licai/21944381.htm

转载于:https://www.cnblogs.com/huqingchen/p/5979936.html

java反射机制之Method invoke执行调用方法例子相关推荐

  1. JAVA 反射 动态获取类,并调用方法

    Class<?> clazz = Class.forName("cn.walle.sysGrid.MyMethod");Object show = (Object) c ...

  2. 【面试】Java 反射机制(常见面试题)

    文章目录 前言 一.反射是什么? 二.为什么要有反射 三.反射 API 3.1 获取 Class 对象的三种方式 3.2 获取成员变量 3.3 获取构造方法 3.4.获取非构造方法 四.实践 五.常见 ...

  3. java反射机制调用带参数的方法_Java反射机制:跟着代码学反射

    1. 前言 在OOP的世界里,万物皆对象.也就是说,我们可以将任何东西抽象成一个对象. 比如人,可以抽象成一个Person类,通过new Person()来实例化一个对象:再比如鸭子,可以抽象成一个D ...

  4. Java 反射机制详解:私有方法调用头大?如何通过反射调用类中的私有方法?

    文章目录 前言 一.私有方法在本类中直接调用 1.1.在本类中实例化,调用私有方法 1.2.尝试在其他类直接调用私有方法(错误示范) 二.使用反射实例化类强制调用私有方法 2.1.使用类加载器加载被调 ...

  5. java invoke 泛型_利用Java反射机制和泛型,全自动解析json

    有啦这个简直,太爽啦, 利用Java 反射机制,利用Class 就可以得到 类的 变量  Field[] fields=cls.getDeclaredFields(); 还可以通过类中 的方法名字 去 ...

  6. 利用Java反射机制调用含数组参数的方法

    http://yourmitra.wordpress.com/2008/09/26/using-java-reflection-to-invoke-a-method-with-array-parame ...

  7. 利用Java反射机制调用类的私有方法

    利用Java反射机制调用类的私有方法 引言 来吧·展示 参考链接 引言 如何调用其他类的私有方法呢? 可以利用Java的反射机制,去调用其他类的私有方法 来吧·展示 package cn.learn. ...

  8. JAVA反射机制、Class类及动态加载、成员变量构造方法其他方法的反射与调用、代理模式AOP

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语言 ...

  9. java基础-java反射机制

    2019独角兽企业重金招聘Python工程师标准>>> 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩" ...

  10. 利用java反射机制进行对象操作

    我们经常使用COMMONS-BEANUTILS包来进行bean的操作,例如从map到bean获从bean到map的映射,那么实现的原理是什么呢,下面举个简单的操作的例子:首先,我建立一个bean pu ...

最新文章

  1. 配置apache虚拟host
  2. 天籁数学——数列篇(1)
  3. 游戏开发需要掌握的法则有哪些?
  4. 如何添加行号 c语言,如何为程序代码加上行号
  5. 算命师傅的好帮手:一款简单好用又使用的排盘工具--灵棋排盘
  6. C语言入门——取余运算
  7. U盘文件格式简单介绍
  8. Sass -- 基础知识与环境搭建
  9. Java语言Switch语句详解(一)
  10. vue关于接口请求数据过大导致浏览器崩溃
  11. 怎么通过抖音带货赚钱?史上最全面抖音带货攻略
  12. 大型web系统数据缓存设计
  13. 客户期望,客户满意度,客户体验和客户忠诚度之间存在的联系
  14. Hduoj1011【树状DP】
  15. Java 中continue基础用法
  16. 大中华地区的商业IMAX影院(更新至2010年7月)
  17. 求珠穆朗玛峰的高度和判断密码是否正确
  18. dell笔记本电脑win7系统无法连接wifi6路由器的解决办法
  19. HTML下拉选框加倒三角,CSS给选中元素增加倒三角形
  20. 爱情保险是什么,真的有爱情保险吗

热门文章

  1. java中随机产生一个数_在Java中产生随机数的两个方法
  2. 临危受命 青力支持:“信豫链”及时上线 保障河南中小企业带“资”复工
  3. 技术小卡之Redis 管道技术
  4. 【requireJS路径加载】与程序员小卡的交流
  5. APP推广真的有捷径么?
  6. PCBA方案设计——人体电子秤芯片方案
  7. iPhone手机分辨率
  8. JAVA相关基础知识
  9. 记录一次接入Unity IAP Tapjoy 等SDK的过程,坑了一周,快吐血了
  10. 在线html5行情,Html5版本的全套股票行情图