< prev index next >

src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java

Print this page




  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.reflect;
  27 
  28 import java.io.ByteArrayOutputStream;
  29 import java.io.DataOutputStream;
  30 import java.io.File;
  31 import java.io.IOException;
  32 import java.io.OutputStream;
  33 import java.lang.reflect.Array;
  34 import java.lang.reflect.Method;
  35 import java.nio.file.Files;
  36 import java.nio.file.Path;
  37 import java.util.ArrayList;
  38 import java.util.HashMap;
  39 import java.util.LinkedList;
  40 import java.util.List;
  41 import java.util.ListIterator;
  42 import java.util.Map;
  43 import sun.security.action.GetBooleanAction;
  44 
  45 /**
  46  * ProxyGenerator contains the code to generate a dynamic proxy class
  47  * for the java.lang.reflect.Proxy API.
  48  *
  49  * The external interfaces to ProxyGenerator is the static
  50  * "generateProxyClass" method.
  51  *
  52  * @author      Peter Jones
  53  * @since       1.3
  54  */


1395      * supplied stream.
1396      */
1397     private void code_ipush(int value, DataOutputStream out)
1398         throws IOException
1399     {
1400         if (value >= -1 && value <= 5) {
1401             out.writeByte(opc_iconst_0 + value);
1402         } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
1403             out.writeByte(opc_bipush);
1404             out.writeByte(value & 0xFF);
1405         } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
1406             out.writeByte(opc_sipush);
1407             out.writeShort(value & 0xFFFF);
1408         } else {
1409             throw new AssertionError();
1410         }
1411     }
1412 
1413     /**
1414      * Generate code to invoke the Class.forName with the name of the given
1415      * class to get its Class object at runtime.  The code is written to
1416      * the supplied stream.  Note that the code generated by this method
1417      * may caused the checked ClassNotFoundException to be thrown.


1418      */
1419     private void codeClassForName(Class<?> cl, DataOutputStream out)
1420         throws IOException
1421     {
1422         code_ldc(cp.getString(cl.getName()), out);
1423 
1424         out.writeByte(opc_invokestatic);
1425         out.writeShort(cp.getMethodRef(
1426             "java/lang/Class",
1427             "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));







1428     }
1429 
1430 
1431     /*
1432      * ==================== General Utility Methods ====================
1433      */
1434 
1435     /**
1436      * Convert a fully qualified class name that uses '.' as the package
1437      * separator, the external representation used by the Java language
1438      * and APIs, to a fully qualified class name that uses '/' as the
1439      * package separator, the representation used in the class file
1440      * format (see JVMS section 4.2).
1441      */
1442     private static String dotToSlash(String name) {
1443         return name.replace('.', '/');
1444     }
1445 
1446     /**
1447      * Return the "method descriptor" string for a method with the given


1471     }
1472 
1473     /**
1474      * Return the "field type" string for the given type, appropriate for
1475      * a field descriptor, a parameter descriptor, or a return descriptor
1476      * other than "void".  See JVMS section 4.3.2.
1477      */
1478     private static String getFieldType(Class<?> type) {
1479         if (type.isPrimitive()) {
1480             return PrimitiveTypeInfo.get(type).baseTypeString;
1481         } else if (type.isArray()) {
1482             /*
1483              * According to JLS 20.3.2, the getName() method on Class does
1484              * return the VM type descriptor format for array classes (only);
1485              * using that should be quicker than the otherwise obvious code:
1486              *
1487              *     return "[" + getTypeDescriptor(type.getComponentType());
1488              */
1489             return type.getName().replace('.', '/');
1490         } else {
1491             return "L" + dotToSlash(type.getName()) + ";";

1492         }
1493     }
1494 
1495     /**
1496      * Returns a human-readable string representing the signature of a
1497      * method with the given name and parameter types.
1498      */
1499     private static String getFriendlyMethodSignature(String name,
1500                                                      Class<?>[] parameterTypes)
1501     {
1502         StringBuilder sig = new StringBuilder(name);
1503         sig.append('(');
1504         for (int i = 0; i < parameterTypes.length; i++) {
1505             if (i > 0) {
1506                 sig.append(',');
1507             }
1508             Class<?> parameterType = parameterTypes[i];
1509             int dimensions = 0;
1510             while (parameterType.isArray()) {
1511                 parameterType = parameterType.getComponentType();




  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.reflect;
  27 
  28 import java.io.ByteArrayOutputStream;
  29 import java.io.DataOutputStream;
  30 import java.io.File;
  31 import java.io.IOException;
  32 import java.io.OutputStream;


  33 import java.nio.file.Files;
  34 import java.nio.file.Path;
  35 import java.util.ArrayList;
  36 import java.util.HashMap;
  37 import java.util.LinkedList;
  38 import java.util.List;
  39 import java.util.ListIterator;
  40 import java.util.Map;
  41 import sun.security.action.GetBooleanAction;
  42 
  43 /**
  44  * ProxyGenerator contains the code to generate a dynamic proxy class
  45  * for the java.lang.reflect.Proxy API.
  46  *
  47  * The external interfaces to ProxyGenerator is the static
  48  * "generateProxyClass" method.
  49  *
  50  * @author      Peter Jones
  51  * @since       1.3
  52  */


1393      * supplied stream.
1394      */
1395     private void code_ipush(int value, DataOutputStream out)
1396         throws IOException
1397     {
1398         if (value >= -1 && value <= 5) {
1399             out.writeByte(opc_iconst_0 + value);
1400         } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
1401             out.writeByte(opc_bipush);
1402             out.writeByte(value & 0xFF);
1403         } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
1404             out.writeByte(opc_sipush);
1405             out.writeShort(value & 0xFFFF);
1406         } else {
1407             throw new AssertionError();
1408         }
1409     }
1410 
1411     /**
1412      * Generate code to invoke the Class.forName with the name of the given
1413      * class to get its Class object at runtime.  And also generate code
1414      * to invoke Class.asValueBox if the class is regular value type.
1415      *
1416      * The code is written to the supplied stream.  Note that the code generated
1417      * by this method may caused the checked ClassNotFoundException to be thrown.
1418      */
1419     private void codeClassForName(Class<?> cl, DataOutputStream out)
1420         throws IOException
1421     {
1422         code_ldc(cp.getString(cl.getName()), out);
1423 
1424         out.writeByte(opc_invokestatic);
1425         out.writeShort(cp.getMethodRef(
1426             "java/lang/Class",
1427             "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
1428 
1429         if (cl.isValue() && cl == cl.asValueType()) {
1430             out.writeByte(opc_invokevirtual);
1431             out.writeShort(cp.getMethodRef(
1432                 "java/lang/Class",
1433                 "asValueType", "()Ljava/lang/Class;"));
1434         }
1435     }
1436 
1437 
1438     /*
1439      * ==================== General Utility Methods ====================
1440      */
1441 
1442     /**
1443      * Convert a fully qualified class name that uses '.' as the package
1444      * separator, the external representation used by the Java language
1445      * and APIs, to a fully qualified class name that uses '/' as the
1446      * package separator, the representation used in the class file
1447      * format (see JVMS section 4.2).
1448      */
1449     private static String dotToSlash(String name) {
1450         return name.replace('.', '/');
1451     }
1452 
1453     /**
1454      * Return the "method descriptor" string for a method with the given


1478     }
1479 
1480     /**
1481      * Return the "field type" string for the given type, appropriate for
1482      * a field descriptor, a parameter descriptor, or a return descriptor
1483      * other than "void".  See JVMS section 4.3.2.
1484      */
1485     private static String getFieldType(Class<?> type) {
1486         if (type.isPrimitive()) {
1487             return PrimitiveTypeInfo.get(type).baseTypeString;
1488         } else if (type.isArray()) {
1489             /*
1490              * According to JLS 20.3.2, the getName() method on Class does
1491              * return the VM type descriptor format for array classes (only);
1492              * using that should be quicker than the otherwise obvious code:
1493              *
1494              *     return "[" + getTypeDescriptor(type.getComponentType());
1495              */
1496             return type.getName().replace('.', '/');
1497         } else {
1498             char prefix = type.isValue() && type == type.asValueType() ? 'Q' : 'L';
1499             return prefix + dotToSlash(type.getName()) + ";";
1500         }
1501     }
1502 
1503     /**
1504      * Returns a human-readable string representing the signature of a
1505      * method with the given name and parameter types.
1506      */
1507     private static String getFriendlyMethodSignature(String name,
1508                                                      Class<?>[] parameterTypes)
1509     {
1510         StringBuilder sig = new StringBuilder(name);
1511         sig.append('(');
1512         for (int i = 0; i < parameterTypes.length; i++) {
1513             if (i > 0) {
1514                 sig.append(',');
1515             }
1516             Class<?> parameterType = parameterTypes[i];
1517             int dimensions = 0;
1518             while (parameterType.isArray()) {
1519                 parameterType = parameterType.getComponentType();


< prev index next >