且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用ABAP的RTTI和Java反射机制访问static private属性

更新时间:2022-04-19 06:10:59

In ABAP we can define a static attribute for a class via keyword CLASS-DATA, whose validity is not associated with instances of a class but with the class itself. In order to prove this fact I use the following simple Pointer class for demonstration:

class ZCL_POINT definition

 public

 final

 create public .

public section.

 data X type I .

 methods CONSTRUCTOR

   importing

     !IV_X type I

     !IV_Y type I .

private section.

 data Y type I .

 class-data COUNT type I .

ENDCLASS.

CLASS ZCL_POINT IMPLEMENTATION.

 method CONSTRUCTOR.

   me->x = iv_x.

   me->y = iv_y.

   count = count + 1.

 endmethod.

ENDCLASS.In this class, static attribute count is responsible to maintain the number of created Point instances.

Then create four point instances:data(a) = new zcl_point( iv_x = 1 iv_y = 1 ).

data(b) = new zcl_point( iv_x = 1 iv_y = 2 ).

data(c) = new zcl_point( iv_x = 1 iv_y = 3 ).

data(d) = new zcl_point( iv_x = 1 iv_y = 4 ).Via any variable of a, b, c or d, we can monitor the value of count in debugger.

使用ABAP的RTTI和Java反射机制访问static private属性Can we access the static attribute of a class without object instance in debugger?

Since in theory the static attribute belongs to class instead of any dedicated object instance, so question comes: is there approach to monitor the static attribute value in ABAP debugger directly from class instead? Yes it is possible.


(1) type text “{C:ZCL_POINT} in debugger and press enter key



使用ABAP的RTTI和Java反射机制访问static private属性(2) double click, and you can see the attribute value is directly maintained in class ZCL_POINT, without any object instance created on top of it.


使用ABAP的RTTI和Java反射机制访问static private属性

And I try to change its visibility dynamically via class descriptor via the following code and actually it is not possible:

data(lo) = CAST cl_abap_objectdescr( cl_abap_classdescr=>describe_by_name( 'ZCL_POINT' ) ).

read TABLE lo->attributes ASSIGNING FIELD-SYMBOL(<count>) WITH KEY name = 'COUNT'.

CHECK SY-SUBRC = 0.

<count>-visibility = 'U'.Since the structure is read-only and not editable outside cl_abap_objectdescr.使用ABAP的RTTI和Java反射机制访问static private属性使用ABAP的RTTI和Java反射机制访问static private属性This makes sense otherwise the encapsulation will be violated. Just check many other attribute marked as read-only in Class/Object descriptor class.


使用ABAP的RTTI和Java反射机制访问static private属性

Reflection in Java

Check the following code which demonstrates how to access private static attribute value in code via Reflection.import java.lang.reflect.Field;

public class Point {

private int x;

private int y;

static private int count = 0;

public Point(int x, int y){

 this.x = x;

 this.y = y;

 count++;

}

private static void accessStaticPrivate(Point point){

 Class classObject = point.getClass();

 try {

  Field countField = classObject.getDeclaredField("count");

  System.out.println("count: " + countField.get(point));

 } catch (NoSuchFieldException | SecurityException | IllegalArgumentException

   | IllegalAccessException e1 ) {

  e1.printStackTrace();

 }  

}

public static void main(String[] arg){

 Point a = new Point(1,2);

 accessStaticPrivate(a);

 

 Point b = new Point(1,3);

 accessStaticPrivate(b);

 

 Point c = new Point(1,4);

 accessStaticPrivate(c);

 

 Point d = new Point(1,5);

 accessStaticPrivate(d);

}

}For ABAPer it is easy to understand the usage of Class object in Java by just comparing it with CL_ABAP_CLASSDESCR in ABAP.

When running this small program locally, you will get output in console:


count: 1

count: 2

count: 3

count: 4Unlike RTTI in ABAP, Java reflection can sometimes lead to security issues, see one example how Java Singleton would be bypassed in blog Singleton bypass – ABAP and Java.