专栏首页代码拾遗反射基础之Method

反射基础之Method

获取方法类型信息

一个方法声明包括:方法名,描述符,参数,返回类型和异常。可以通过java.lang.reflect.Method类获取这些信息。 下面的例子说明了如何获取一个类中所有的方法,根据名字获取方法的返回类型,参数,异常等。

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import static java.lang.System.out;

public class MethodSpy {
    private static final String  fmt = "%24s: %s%n";

    // for the morbidly curious
    <E extends RuntimeException> void genericThrow() throws E {}

    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        Method[] allMethods = c.getDeclaredMethods();
        for (Method m : allMethods) {
        if (!m.getName().equals(args[1])) {
            continue;
        }
        out.format("%s%n", m.toGenericString());

        out.format(fmt, "ReturnType", m.getReturnType());
        out.format(fmt, "GenericReturnType", m.getGenericReturnType());

        Class<?>[] pType  = m.getParameterTypes();
        Type[] gpType = m.getGenericParameterTypes();
        for (int i = 0; i < pType.length; i++) {
            out.format(fmt,"ParameterType", pType[i]);
            out.format(fmt,"GenericParameterType", gpType[i]);
        }

        Class<?>[] xType  = m.getExceptionTypes();
        Type[] gxType = m.getGenericExceptionTypes();
        for (int i = 0; i < xType.length; i++) {
            out.format(fmt,"ExceptionType", xType[i]);
            out.format(fmt,"GenericExceptionType", gxType[i]);
        }
        }

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    }
    }
}

运行:

$ java MethodSpy java.lang.Class getConstructor
public java.lang.reflect.Constructor<T> java.lang.Class.getConstructor
  (java.lang.Class<?>[]) throws java.lang.NoSuchMethodException,
  java.lang.SecurityException
              ReturnType: class java.lang.reflect.Constructor
       GenericReturnType: java.lang.reflect.Constructor<T>
           ParameterType: class [Ljava.lang.Class;
    GenericParameterType: java.lang.Class<?>[]
           ExceptionType: class java.lang.NoSuchMethodException
    GenericExceptionType: class java.lang.NoSuchMethodException
           ExceptionType: class java.lang.SecurityException
    GenericExceptionType: class java.lang.SecurityException]

源码中方法定义public Constructor<T> getConstructor(Class<?>... parameterTypes)。 首先注意,返回类型和参数类型是泛型类型。如果在class文件中提供了Signature Attribute Method.getGenericReturnType() 计算出其泛型类型。如果没有提供则使用Method.getReturnType(),这个并不会带有泛型信息。 其次注意,parameterTypes 是可变参数,类型是java.lang.Class 。可变参数列表被表示为一维数组。可以通过Method.isVarArgs() 来区别是否是可变参数。 如果返回值是泛型运行如下:

$ java MethodSpy java.lang.Class cast
public T java.lang.Class.cast(java.lang.Object)
              ReturnType: class java.lang.Object
       GenericReturnType: T
           ParameterType: class java.lang.Object
    GenericParameterType: class java.lang.Object

对于重载函数则会显示所有的重载函数信息:

$ java MethodSpy java.io.PrintStream format
public java.io.PrintStream java.io.PrintStream.format
  (java.util.Locale,java.lang.String,java.lang.Object[])
              ReturnType: class java.io.PrintStream
       GenericReturnType: class java.io.PrintStream
           ParameterType: class java.util.Locale
    GenericParameterType: class java.util.Locale
           ParameterType: class java.lang.String
    GenericParameterType: class java.lang.String
           ParameterType: class [Ljava.lang.Object;
    GenericParameterType: class [Ljava.lang.Object;
public java.io.PrintStream java.io.PrintStream.format
  (java.lang.String,java.lang.Object[])
              ReturnType: class java.io.PrintStream
       GenericReturnType: class java.io.PrintStream
           ParameterType: class java.lang.String
    GenericParameterType: class java.lang.String
           ParameterType: class [Ljava.lang.Object;
    GenericParameterType: class [Ljava.lang.Object;]]]]
获取方法的参数名

可以通过java.lang.reflect.Executable.getParameters()方法获取方法的参数名,Method和Constructor都继承与java.lang.reflect.Executable,所有都可以使用这个函数。然后class文件默认并不保存方法这些信息。因为很多工具生成和获取class文件的时候都不会希望有大量的参数名字信息。尤其是这些工具处理大的class文件的时候,JVM将会使用更多的内存。另外,参数名,例如:secret或者password,可能会暴露一些安全敏感的信息。 可以在编译的时候使用-parameters 将参数名保存到class文件中。 下面的例子展示了如何获取参数信息:

import java.lang.reflect.*;
import java.util.function.*;
import static java.lang.System.out;

public class MethodParameterSpy {

    private static final String  fmt = "%24s: %s%n";

    // for the morbidly curious
    <E extends RuntimeException> void genericThrow() throws E {}

    public static void printClassConstructors(Class c) {
        Constructor[] allConstructors = c.getConstructors();
        out.format(fmt, "Number of constructors", allConstructors.length);
        for (Constructor currentConstructor : allConstructors) {
            printConstructor(currentConstructor);
        }  
        Constructor[] allDeclConst = c.getDeclaredConstructors();
        out.format(fmt, "Number of declared constructors",
            allDeclConst.length);
        for (Constructor currentDeclConst : allDeclConst) {
            printConstructor(currentDeclConst);
        }          
    }

    public static void printClassMethods(Class c) {
       Method[] allMethods = c.getDeclaredMethods();
        out.format(fmt, "Number of methods", allMethods.length);
        for (Method m : allMethods) {
            printMethod(m);
        }        
    }

    public static void printConstructor(Constructor c) {
        out.format("%s%n", c.toGenericString());
        Parameter[] params = c.getParameters();
        out.format(fmt, "Number of parameters", params.length);
        for (int i = 0; i < params.length; i++) {
            printParameter(params[i]);
        }
    }

    public static void printMethod(Method m) {
        out.format("%s%n", m.toGenericString());
        out.format(fmt, "Return type", m.getReturnType());
        out.format(fmt, "Generic return type", m.getGenericReturnType());

        Parameter[] params = m.getParameters();
        for (int i = 0; i < params.length; i++) {
            printParameter(params[i]);
        }
    }

    public static void printParameter(Parameter p) {
        out.format(fmt, "Parameter class", p.getType());
        out.format(fmt, "Parameter name", p.getName());
        out.format(fmt, "Modifiers", p.getModifiers());
        out.format(fmt, "Is implicit?", p.isImplicit());
        out.format(fmt, "Is name present?", p.isNamePresent());
        out.format(fmt, "Is synthetic?", p.isSynthetic());
    }

    public static void main(String... args) {        

        try {
            printClassConstructors(Class.forName(args[0]));
            printClassMethods(Class.forName(args[0]));
        } catch (ClassNotFoundException x) {
            x.printStackTrace();
        }
    }
}

编译时记得使用-parameter参数,运行 结果如下:

Number of constructors: 1

Constructor #1
public ExampleMethods()

Number of declared constructors: 1

Declared constructor #1
public ExampleMethods()

Number of methods: 4

Method #1
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
             Return type: boolean
     Generic return type: boolean
         Parameter class: class java.lang.String
          Parameter name: stringParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false
         Parameter class: int
          Parameter name: intParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #2
public int ExampleMethods.varArgsMethod(java.lang.String...)
             Return type: int
     Generic return type: int
         Parameter class: class [Ljava.lang.String;
          Parameter name: manyStrings
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #3
public boolean ExampleMethods.methodWithList(java.util.List<java.lang.String>)
             Return type: boolean
     Generic return type: boolean
         Parameter class: interface java.util.List
          Parameter name: listParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #4
public <T> void ExampleMethods.genericMethod(T[],java.util.Collection<T>)
             Return type: void
     Generic return type: void
         Parameter class: class [Ljava.lang.Object;
          Parameter name: a
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false
         Parameter class: interface java.util.Collection
          Parameter name: c
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Parameter 类的方法是用:

  • getType(): 返回Class对象,表明参数的类型
  • getName(): 返回参数名子。如果有名字则返回名字,如果没有合成参数名argN N是参数的顺序。

例如如果不是用-parameter 参数:

public boolean ExampleMethods.simpleMethod(java.lang.String,int)
             Return type: boolean
     Generic return type: boolean
         Parameter class: class java.lang.String
          Parameter name: arg0
               Modifiers: 0
            Is implicit?: false
        Is name present?: false
           Is synthetic?: false
         Parameter class: int
          Parameter name: arg1
               Modifiers: 0
            Is implicit?: false
        Is name present?: false
           Is synthetic?: false
  • getModifiers(): 返回代表修饰符的数字。
  • isImplicit(): 如果参数是隐式声明则返回true
  • isNamePresent(): 如果class中有参数名信息返回true。
  • isSynthetic(): 如果参数既没有显示也没有隐式的在源码中声明,返回true。
隐式和合成参数

某些构造函数是隐式声明在源码中的。例如ExampleMethods没有一个显式声明的构造函数则会默认一个隐式的构造函数。如:

Number of declared constructors: 1
public ExampleMethods()

对于内部函数:

public class MethodParameterExamples {
    public class InnerClass { }
}

InnerClass是一个非静态的类,其内部也会有一个隐式的构造函数声明,但是这个隐式构造器会包含一个参数,如下,包含了其外围函数的引用:

public class MethodParameterExamples {
    public class InnerClass {
        final MethodParameterExamples parent;
        InnerClass(final MethodParameterExamples this$0) {
            parent = this$0; 
        }
    }
}

所以运行MethodParameterExample会得到如下结果:

public MethodParameterExamples$InnerClass(MethodParameterExamples)
         Parameter class: class MethodParameterExamples
          Parameter name: this$0
               Modifiers: 32784
            Is implicit?: true
        Is name present?: true
           Is synthetic?: false

如果一个构造器既不是显式声明的也不是隐式声明的难而是有Java编译器生成的则被标记为合成的。例如:

public class MethodParameterExamples {
    enum Colors {
        RED, WHITE;
    }
}

对于enum java编译的时候会补充完其完整信息:

final class Colors extends java.lang.Enum<Colors> {
    public final static Colors RED = new Colors("RED", 0);
    public final static Colors BLUE = new Colors("WHITE", 1);

    private final static values = new Colors[]{ RED, BLUE };

    private Colors(String name, int ordinal) {
        super(name, ordinal);
    }

    public static Colors[] values(){
        return values;
    }

    public static Colors valueOf(String name){
        return (Colors)java.lang.Enum.valueOf(Colors.class, name);
    }
}

这也就是为什么enum不能继承类只能继承接口的原因,因为他已经击沉过了Enum类。

获取并解析方法修饰符

方法的修饰符有:

  • 访问修饰符:pubic,protected,private
  • 静态修饰符:static
  • 不可变修饰符: final
  • 抽象修饰符: abstract
  • 同步修饰符: synchronized
  • 本地方法修饰符: native
  • 严格浮点修饰符: strictfp
  • 注解

下例现实了如何获取修饰符信息:

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import static java.lang.System.out;

public class MethodModifierSpy {

    private static int count;
    private static synchronized void inc() { count++; }
    private static synchronized int cnt() { return count; }

    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        Method[] allMethods = c.getDeclaredMethods();
        for (Method m : allMethods) {
        if (!m.getName().equals(args[1])) {
            continue;
        }
        out.format("%s%n", m.toGenericString());
        out.format("  Modifiers:  %s%n",
               Modifier.toString(m.getModifiers()));
        out.format("  [ synthetic=%-5b var_args=%-5b bridge=%-5b ]%n",
               m.isSynthetic(), m.isVarArgs(), m.isBridge());
        inc();
        }
        out.format("%d matching overload%s found%n", cnt(),
               (cnt() == 1 ? "" : "s"));

        // production code should handle this exception more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    }
    }
}

运行结果如下:

$ java MethodModifierSpy java.lang.Object wait
public final void java.lang.Object.wait() throws java.lang.InterruptedException
  Modifiers:  public final
  [ synthetic=false var_args=false bridge=false ]
public final void java.lang.Object.wait(long,int)
  throws java.lang.InterruptedException
  Modifiers:  public final
  [ synthetic=false var_args=false bridge=false ]
public final native void java.lang.Object.wait(long)
  throws java.lang.InterruptedException
  Modifiers:  public final native
  [ synthetic=false var_args=false bridge=false ]
3 matching overloads found

$ java MethodModifierSpy java.lang.StrictMath toRadians
public static double java.lang.StrictMath.toRadians(double)
  Modifiers:  public static strictfp
  [ synthetic=false var_args=false bridge=false ]
1 matching overload found

$ java MethodModifierSpy MethodModifierSpy inc
private synchronized void MethodModifierSpy.inc()
  Modifiers: private synchronized
  [ synthetic=false var_args=false bridge=false ]
1 matching overload found

$ java MethodModifierSpy java.lang.Class getConstructor
public java.lang.reflect.Constructor<T> java.lang.Class.getConstructor
  (java.lang.Class<T>[]) throws java.lang.NoSuchMethodException,
  java.lang.SecurityException
  Modifiers: public transient
  [ synthetic=false var_args=true bridge=false ]
1 matching overload found

$ java MethodModifierSpy java.lang.String compareTo
public int java.lang.String.compareTo(java.lang.String)
  Modifiers: public
  [ synthetic=false var_args=false bridge=false ]
public int java.lang.String.compareTo(java.lang.Object)
  Modifiers: public volatile
  [ synthetic=true  var_args=false bridge=true  ]
2 matching overloads found
方法调用

可以使用java.lang.reflect.Method.invoke()方法调用反射获取的方法。第一个参数是被调用的对象实例,如果是static函数,第一个参数可以是null,接下来的参数是函数的参数。如果执行发生错误,会被java.lang.reflect.InvocationTargetException异常包装,函数原有异常可以功过InvocationTargetExcetpion.getCause()获取。

查找指定方法并执行:

示例:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Locale;
import static java.lang.System.out;
import static java.lang.System.err;

public class Deet<T> {
    private boolean testDeet(Locale l) {
    // getISO3Language() may throw a MissingResourceException
    out.format("Locale = %s, ISO Language Code = %s%n", l.getDisplayName(), l.getISO3Language());
    return true;
    }

    private int testFoo(Locale l) { return 0; }
    private boolean testBar() { return true; }

    public static void main(String... args) {
    if (args.length != 4) {
        err.format("Usage: java Deet <classname> <langauge> <country> <variant>%n");
        return;
    }

    try {
        Class<?> c = Class.forName(args[0]);
        Object t = c.newInstance();

        Method[] allMethods = c.getDeclaredMethods();
        for (Method m : allMethods) {
        String mname = m.getName();
        if (!mname.startsWith("test")
            || (m.getGenericReturnType() != boolean.class)) {
            continue;
        }
        Type[] pType = m.getGenericParameterTypes();
        if ((pType.length != 1)
            || Locale.class.isAssignableFrom(pType[0].getClass())) {
            continue;
        }

        out.format("invoking %s()%n", mname);
        try {
            m.setAccessible(true);
            Object o = m.invoke(t, new Locale(args[1], args[2], args[3]));
            out.format("%s() returned %b%n", mname, (Boolean) o);

        // Handle any exceptions thrown by method to be invoked.
        } catch (InvocationTargetException x) {
            Throwable cause = x.getCause();
            err.format("invocation of %s failed: %s%n",
                   mname, cause.getMessage());
        }
        }

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    } catch (InstantiationException x) {
        x.printStackTrace();
    } catch (IllegalAccessException x) {
        x.printStackTrace();
    }
    }
}

Deet调用getDelcaredMethods()返回所有的方法。Class.isAssignableFrom() 用来检测参数类型和调用的方法的参数类型是否一致。因为Locale是final类型的,所以可以使用Local.class == pType[0].getClass()来测试,不过Class.isAssignableFrom()更常用。 运行结果:

$ java Deet Deet ja JP JP
invoking testDeet()
Locale = Japanese (Japan,JP), 
ISO Language Code = jpn
testDeet() returned true

$ java Deet Deet xx XX XX
invoking testDeet()
invocation of testDeet failed: 
Couldn't find 3-letter language code for xx

可变参数调用:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class InvokeMain {
    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        Class[] argTypes = new Class[] { String[].class };
        Method main = c.getDeclaredMethod("main", argTypes);
        String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
        System.out.format("invoking %s.main()%n", c.getName());
        main.invoke(null, (Object)mainArgs);

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    } catch (NoSuchMethodException x) {
        x.printStackTrace();
    } catch (IllegalAccessException x) {
        x.printStackTrace();
    } catch (InvocationTargetException x) {
        x.printStackTrace();
    }
    }
}

运行结果:

$ java InvokeMain Deet Deet ja JP JP
invoking Deet.main()
invoking testDeet()
Locale = Japanese (Japan,JP), 
ISO Language Code = jpn
testDeet() returned true
问题排查
由于类型擦除导致的 NoSuchMethodException

示例:

import java.lang.reflect.Method;

public class MethodTrouble<T>  {
    public void lookup(T t) {}
    public void find(Integer i) {}

    public static void main(String... args) {
    try {
        String mName = args[0];
        Class cArg = Class.forName(args[1]);
        Class<?> c = (new MethodTrouble<Integer>()).getClass();
        Method m = c.getMethod(mName, cArg);
        System.out.format("Found:%n  %s%n", m.toGenericString());

        // production code should handle these exceptions more gracefully
    } catch (NoSuchMethodException x) {
        x.printStackTrace();
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    }
    }
}

运行结果:

$ java MethodTrouble lookup java.lang.Integer
java.lang.NoSuchMethodException: MethodTrouble.lookup(java.lang.Integer)
        at java.lang.Class.getMethod(Class.java:1605)
        at MethodTrouble.main(MethodTrouble.java:12)

$ java MethodTrouble lookup java.lang.Object
Found:
  public void MethodTrouble.lookup(T)

因为方法声明中有反省类型,编译器会将会使用他的上界替换泛型类型,在这个例子中T的上界是Object。因此编译后无法找到lookup(Integer)的方法。

调用方法是抛出 IllegalAccessException
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class AnotherClass {
    private void m() {}
}

public class MethodTroubleAgain {
    public static void main(String... args) {
    AnotherClass ac = new AnotherClass();
    try {
        Class<?> c = ac.getClass();
        Method m = c.getDeclaredMethod("m");
//          m.setAccessible(true);      // solution
        Object o = m.invoke(ac);    // IllegalAccessException

        // production code should handle these exceptions more gracefully
    } catch (NoSuchMethodException x) {
        x.printStackTrace();
    } catch (InvocationTargetException x) {
        x.printStackTrace();
    } catch (IllegalAccessException x) {
        x.printStackTrace();
    }
    }
}

调用结果:

$ java MethodTroubleAgain
java.lang.IllegalAccessException: Class MethodTroubleAgain can not access a
  member of class AnotherClass with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.reflect.Method.invoke(Method.java:588)
        at MethodTroubleAgain.main(MethodTroubleAgain.java:15)

因为访问修饰符是private所以导致无法调用。

调用invoke()时抛出 IllegalArgumentException

示例:

import java.lang.reflect.Method;

public class MethodTroubleToo {
    public void ping() { System.out.format("PONG!%n"); }

    public static void main(String... args) {
    try {
        MethodTroubleToo mtt = new MethodTroubleToo();
        Method m = MethodTroubleToo.class.getMethod("ping");

        switch(Integer.parseInt(args[0])) {
        case 0:
        m.invoke(mtt);                 // works
        break;
        case 1:
        m.invoke(mtt, null);           // works (expect compiler warning)
        break;
        case 2:
        Object arg2 = null;
        m.invoke(mtt, arg2);           // IllegalArgumentException
        break;
        case 3:
        m.invoke(mtt, new Object[0]);  // works
        break;
        case 4:
        Object arg4 = new Object[0];
        m.invoke(mtt, arg4);           // IllegalArgumentException
        break;
        default:
        System.out.format("Test not found%n");
        }

        // production code should handle these exceptions more gracefully
    } catch (Exception x) {
        x.printStackTrace();
    }
    }
}

运行结果:

$ java MethodTroubleToo 1
PONG!
$ javac MethodTroubleToo.java
MethodTroubleToo.java:16: warning: non-varargs call of varargs method with
  inexact argument type for last parameter;
        m.invoke(mtt, null);           // works (expect compiler warning)
                      ^
  cast to Object for a varargs call
  cast to Object[] for a non-varargs call and to suppress this warning
1 warning
$ java MethodTroubleToo 2
java.lang.IllegalArgumentException: wrong number of arguments
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke
          (NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke
          (DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at MethodTroubleToo.main(MethodTroubleToo.java:21)
$ java MethodTroubleToo 3
PONG!
$ java MethodTroubleToo 4
java.lang.IllegalArgumentException: wrong number of arguments
        at sun.reflect.NativeMethodAccessorImpl.invoke0
          (Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke
          (NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke
          (DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at MethodTroubleToo.main(MethodTroubleToo.java:28)
实际调用的方法抛出异常后抛出 InvocationTargetException 异常

示例:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodTroubleReturns {
    private void drinkMe(int liters) {
    if (liters < 0)
        throw new IllegalArgumentException("I can't drink a negative amount of liquid");
    }

    public static void main(String... args) {
    try {
        MethodTroubleReturns mtr  = new MethodTroubleReturns();
        Class<?> c = mtr.getClass();
        Method m = c.getDeclaredMethod("drinkMe", int.class);
        m.invoke(mtr, -1);

        // production code should handle these exceptions more gracefully
    } catch (InvocationTargetException x) {
        Throwable cause = x.getCause();
        System.err.format("drinkMe() failed: %s%n", cause.getMessage());
    } catch (Exception x) {
        x.printStackTrace();
    }
    }
}

运行结果:

$ java MethodTroubleReturns
drinkMe() failed: I can't drink a negative amount of liquid

本文分享自微信公众号 - 代码拾遗(gh_8f61e8bcb1b1)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 反射基础之Constructor

    构造器的声明包含了:名字,修饰符,参数和异常。可以通过java.lang.reflect.Constructor类获取这些信息。 下面的例子描述了如何获取构造器...

    代码拾遗
  • 反射基础之Field

    java.lang.reflect.Field 类的方法可以查询字段的信息。比如:名字,类型,修饰符和注解。同样也有方法可以动态访问和修改字段的值。

    代码拾遗
  • ​反射基础之Enum

    因为枚举也是一个类,所以也可以通过Field,Method,Constructor的反射API获取其他信息:

    代码拾遗
  • 反射基础之Constructor

    构造器的声明包含了:名字,修饰符,参数和异常。可以通过java.lang.reflect.Constructor类获取这些信息。 下面的例子描述了如何获取构造器...

    代码拾遗
  • 房上的猫:了解java与学习java前的准备

    一.java  概述:   1.通常指完成某些事情的一种既定方式和过程   2.程序可以看做对一系列动作执行过程的描述   3.计算机按照某种顺序完成一系列指令...

    房上的猫
  • 0788-7.1.1-CDP安装SMM服务启动异常

    在CDP7.1.1的安装过程中,添加SMM组件后,配置完数据库信息,启动服务过程中,提示启动Streams Messaging Manager Rest Adm...

    Fayson
  • Java中常见死锁与活锁的实例

    可以看到bThread持有锁0x00000007aaee5758,同时等待0x00000007aaee5748,然而恰好aThread持有锁0x00000007...

    爬蜥
  • Java 学习笔记(1)——java基础语法

    最近抽时间在学习Java,目前有了一点心得,在此记录下来。 由于我自己之前学过C/C++,而Java的语法与C/C++基本类似,所以这一系列文章我并不想从基础...

    Masimaro
  • DateFormat 线程不安全

    一、测试 测试代码如下:  private static SimpleDateFormat sdf = new SimpleDateFormat("yy...

    囚兔
  • 为什么java越来越强势

    ? 目前很多的从业都有这种感觉,突然觉得c/c++就业机会以及升职的空间比java的差距越来越大了,有人就宣称java是目前国内就业最好的语言,说的有点夸张但...

    Java帮帮

扫码关注云+社区

领取腾讯云代金券