Resolve the Field and Method classes in Java

  • 2020-04-01 04:34:08
  • OfStack

The Field class
The Field class defines methods that you can use to query the type of Field and to set or read the value of the Field. Combining these methods with the inherited member method allows us to find out all about the field declarations and manipulate the fields of a particular object or class.

The getGenericType method returns a Type instance representing the declared Type of the field. For trivial types like String or int, this method returns the Class object associated with it, such as string.class and int.classo, for things like List < Stri ng> For a parameterized type like this, the method returns an instance of Parameterizedrype, for example, for a type like T, the method returns a Typevariable instance.

The legacy getType method returns a Class object of the type of the field. For trivial types, this method behaves the same as the getGenericType method. If the declared type of the field is a parameterized type, the getType method returns the Class object to which the parameterized type is erased, the Class object of the original type. For example, for declaration as List < Stri ng> Object, getType will return Li st. class's. If the declared type of the field is a type variable, the getType method returns the class object for erasing the type variable. For example, suppose you have a class FOO< D > , get d ype returns object for a field whose declaration is of type T.

The class object. If FOO is declared FOo< Extends the Number > , then ype under get will return number.class.

We can use the isEnumConstant method to query whether a field is an enumeration constant, or we can use the get and set methods to get and set the value of the field. These methods, which take an object argument and return an Obj ect value, have a generic form, as well as more specialized forms that deal directly with primitive types. All of these methods accept an argument that specifies the object to operate on. For static fields, this object argument is ignored, so you can set it at this point as well

Set to null. The following method prints the value of the short field of an object:


  public static void printShortField(Object o, String name)

  throws NoSuchFieldException . IllegalAccessException

  {

  Field field=o.getClass().getField(name);

  short value=(Short) field.get(o);

  System.out.println(value);

The return value of the get method can be any object referenced by the field, and if the field is of a primitive type, the method returns a wrapper class object of the appropriate type. For our "hort type field, the get method returns the value of a field containing the short type of object, and in it the value assigned to the local variables, the object value will automatically split open a case.

The use of the set method is similar. The method to set the short field to the supplied value might look like this:


  public static voi

  setShortField(Object o . String name . short nv)

  throws NoSuchFieldException . IllegalAccessException

  Field field=0.getClass().getField(name);

  field .set(o .nv);

Although set accepts arguments of type Object, we can simply pass a short value and wrap it with a wrapper transform to wrap it as an Object of type short.

In the above method, an IllegalACcessException is thrown if the domain of the specified object is not accessible and this access control is enforced. If the object passed is of a different type than the field, an illegalArgumentException exception is thrown. If the field is non-static and the passed object reference is null, a NullPointerException is thrown. To access static fields may require initialized to the class, so this method can also throw ExceptionInInitializerError anomalies.

The Field class also has specific methods for getting and setting basic types, for example, we can call getPrimitive7ype and set Primitive7ype on the Field object, where the Primitive7ype is the (uppercase) basic type name. The get method can be used in the following statements:


  short value=field.getshort(o);

The set method can be used in the following statements:


  field.setshort(o, nv);

You can avoid using wrapper class objects in statements declared in either of these ways.

The Field class implements the AnnotatedElement interface, so we can also apply the query to the domain as we did in section 16.2

Notes on.

With the methods described above, we can use the Field object as a way to manipulate arbitrary values, but we should try to avoid using it. Because the Java language in the program compile time capture programming errors as much as possible, so that when we write the code, the use of such as "ield object such indirect method is less, so before they are compiled into code, can prevent more mistakes. Moreover, we can see that in the previous code, if you want to know what would happen, and in general syntax than directly using the domain name, we spent on reading code much larger energy obviously.

Final fields

Normally, setting a field that is declared final will cause an IllegalACcessException to be thrown
Exception, which is what we can expect, because the value of the final field will never change. However, there are special cases -- for example, in custom deserialization (see section 20.8.4) where changing the value of a final Field makes sense, and this can only be done by reflection on an instance Field, provided that setAccessible(true) has been called on the Field object. Note that it is not enough to successfully call setAccessible(true); it must have actually been called.

This capability is provided for highly specialized contexts, not for general purposes, but only to preserve the integrity of the content. If taken out of a particular context, such as custom deserialization, changing the values of final fields can lead to unintended or even catastrophic consequences. Outside of these contexts, there is no guarantee that changes to final fields will be visible. Even in this context, you must ensure that security mechanisms do not impede the execution of the code when coding with this technique. Changing a final field whose value is a constant variable (see section 2.2.3) will cause the change to be invisible, unless the modification is made by using reflection.

Method the class
The method class and the methods it inherits from the member class allow us to get full information about the method declaration:

"Public Type getGenericReturnTypeO: this method returns a Type object of the return Type of the target method. If the target method is declared to return void, the method returns void. Classo

"Public Type[] getgenericparametertype (): this method returns an array of Type objects for all parameter types of the target method, which are stored in the array in the order in which the parameters are declared. If the target method has no arguments, the method returns an empty array.

.publ I c Type [] getGeneri caccepti onTypes Q: this method returns an array of Type objects for all exception types listed in the throws clause, which are stored in the array in the order in which exceptions are declared.

If the target method does not declare any exceptions, the method returns an empty array.

Java also provides getReturnType getParameterTypes and getExceptionTypes method, used to return the Cl as "object rather than the Type object. Just as with field-gettype, parameterized types and type variables are represented by the Class object corresponding to their erasers.

The method class implements the AnnotatedElement, and we can query the annotations applied to methods as discussed in section 16.2. In addition, the Method class provides getParameterAnnotations to provide access to the corresponding annotations used on Method parameters. The getParameterAnnotations method returns an array of annotations, where each element of the outermost array corresponds to the method's parameters. If an argument does not have any annotations, the method returns an Annotation array of length 0 for that argument. If the method represented by the method Object is itself an annotation element, the getDefaultvalue method returns an Object representing the default value of the element. If the method object itself is not an annotation element or it does not have a default value, the method returns null. The method class also implements GenericDeclaration and therefore defines the getTypeParameters method, which returns an array of Typevariable objects. If the given method object does not represent a generic method, the method returns an empty array.

We can use the isvarArgs method to check if a method object is a mutable argument method, and the I sBridge method can be used to check if it is a bridge method

The most interesting use of the Method object is to reflectively call itself:

.public object invoke(object onThis, object...) Args)throws IllegalACcessException, IllegalArgumentException, argetException under nvocation: this method calls the method defined by the method object on the onThis object and USES the value of args to set the parameters of the called method. For non-static methods, onThis actual type will determine which implementation is going to call a method, for the static method, onThis is ignored, and usually will be set to null. The args value number must be the same number of actual parameters and the called method, and the type of these values must be all can be assigned to the parameters of the called method; Otherwise, we will get an llegalArgumentException exception. Note that the last argument to the mutable argument method is an array, so we must fill the array with the actual "mutable" argument we want to pass. If we want to call a method that we don't have access to, the method throws an IllegalACcessException exception. If the called method is not a method of his object under on, the method throws the worker llegalArgumentExcepti on exception. If onThis is null and non-static, the method throws a NO 1PointerException exception. If the method object represents a static method and the class declaring the static method is still in a state to be initialized, the method throws an ExceptionIn worker nitializerError exception. If the called method, the different power, everything will be thrown InvocationTargetException anomalies.

When we use the invoke method, we can either pass the base type directly or use the appropriate wrapper class. The type represented by the wrapper class must be assignable to the parameter type declared by the method. We can use Long,Float, or Double to wrap arguments of type Double, but we can't use Double to wrap arguments of type Long or Float, because Double is not assignable to Long or oat. The object returned by the invoke method is handled the same way as field.get, which returns the basic type of the wrapper class corresponding to them. If the method is declared void, the invoke method returns null,

Simply put, when we invoke a method, we can only use its arguments that are valid in the Java language

Arguments with the same type and value. For example, the following call


  return str.indexof(". ", 8);

Reflection can be written as follows:


  Throwable fa the ure;

  try{

  Method indexM=String.class.

  getMethod("index0f" . String.class . int.class);

  return (Integer) indexM.invoke(str, ",," 8);

  }catch (NoSuchMethodException e){

  failure=e;

  }catch (InvocationTargetException e){

  fa the ure=e .getCause();

  }catch (IllegalAccessException e){

  failure=e;

  }

  throw fa the ure;

While the compiler's security checks for direct calls can only be done at runtime using invoke in the case of reflection, reflection-based code does have the semantic equivalent of security checks for direct calls. Access checks may be performed slightly differently -- the security manager may deny access to a method in our package, even if we can call it directly.

When we can use this form of invocation, there are good reasons to avoid it. But it makes sense to use the invoke or get/set methods when writing debuggers or other generic applications that need to interpret user input as operations on objects. The method object can be used to some extent as a method pointer in similar languages, but we have better tools, especially interfaces, abstract classes, and nested classes, to handle problems that are usually solved with method Pointers in other languages.


Related articles: