📄 type.java
字号:
public int getSort() {
return this.sort;
}
/**
* Returns the number of dimensions of this array type. This method should
* only be used for an array type.
*
* @return the number of dimensions of this array type.
*/
public int getDimensions() {
int i = 1;
while ( this.buf[this.off + i] == '[' ) {
++i;
}
return i;
}
/**
* Returns the type of the elements of this array type. This method should
* only be used for an array type.
*
* @return Returns the type of the elements of this array type.
*/
public Type getElementType() {
return getType( this.buf,
this.off + getDimensions() );
}
/**
* Returns the name of the class corresponding to this type.
*
* @return the fully qualified name of the class corresponding to this type.
*/
public String getClassName() {
switch ( this.sort ) {
case VOID :
return "void";
case BOOLEAN :
return "boolean";
case CHAR :
return "char";
case BYTE :
return "byte";
case SHORT :
return "short";
case INT :
return "int";
case FLOAT :
return "float";
case LONG :
return "long";
case DOUBLE :
return "double";
case ARRAY :
final StringBuffer b = new StringBuffer( getElementType().getClassName() );
for ( int i = getDimensions(); i > 0; --i ) {
b.append( "[]" );
}
return b.toString();
// case OBJECT:
default :
return new String( this.buf,
this.off + 1,
this.len - 2 ).replace( '/',
'.' );
}
}
/**
* Returns the internal name of the class corresponding to this object type.
* The internal name of a class is its fully qualified name, where '.' are
* replaced by '/'. This method should only be used for an object type.
*
* @return the internal name of the class corresponding to this object type.
*/
public String getInternalName() {
return new String( this.buf,
this.off + 1,
this.len - 2 );
}
// ------------------------------------------------------------------------
// Conversion to type descriptors
// ------------------------------------------------------------------------
/**
* Returns the descriptor corresponding to this Java type.
*
* @return the descriptor corresponding to this Java type.
*/
public String getDescriptor() {
final StringBuffer buf = new StringBuffer();
getDescriptor( buf );
return buf.toString();
}
/**
* Returns the descriptor corresponding to the given argument and return
* types.
*
* @param returnType the return type of the method.
* @param argumentTypes the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/
public static String getMethodDescriptor(final Type returnType,
final Type[] argumentTypes) {
final StringBuffer buf = new StringBuffer();
buf.append( '(' );
for ( int i = 0; i < argumentTypes.length; ++i ) {
argumentTypes[i].getDescriptor( buf );
}
buf.append( ')' );
returnType.getDescriptor( buf );
return buf.toString();
}
/**
* Appends the descriptor corresponding to this Java type to the given
* string buffer.
*
* @param buf the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuffer buf) {
switch ( this.sort ) {
case VOID :
buf.append( 'V' );
return;
case BOOLEAN :
buf.append( 'Z' );
return;
case CHAR :
buf.append( 'C' );
return;
case BYTE :
buf.append( 'B' );
return;
case SHORT :
buf.append( 'S' );
return;
case INT :
buf.append( 'I' );
return;
case FLOAT :
buf.append( 'F' );
return;
case LONG :
buf.append( 'J' );
return;
case DOUBLE :
buf.append( 'D' );
return;
// case ARRAY:
// case OBJECT:
default :
buf.append( this.buf,
this.off,
this.len );
}
}
// ------------------------------------------------------------------------
// Direct conversion from classes to type descriptors,
// without intermediate Type objects
// ------------------------------------------------------------------------
/**
* Returns the internal name of the given class. The internal name of a
* class is its fully qualified name, where '.' are replaced by '/'.
*
* @param c an object class.
* @return the internal name of the given class.
*/
public static String getInternalName(final Class c) {
return c.getName().replace( '.',
'/' );
}
/**
* Returns the descriptor corresponding to the given Java type.
*
* @param c an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class.
*/
public static String getDescriptor(final Class c) {
final StringBuffer buf = new StringBuffer();
getDescriptor( buf,
c );
return buf.toString();
}
/**
* Returns the descriptor corresponding to the given method.
*
* @param m a {@link Method Method} object.
* @return the descriptor of the given method.
*/
public static String getMethodDescriptor(final Method m) {
final Class[] parameters = m.getParameterTypes();
final StringBuffer buf = new StringBuffer();
buf.append( '(' );
for ( int i = 0; i < parameters.length; ++i ) {
getDescriptor( buf,
parameters[i] );
}
buf.append( ')' );
getDescriptor( buf,
m.getReturnType() );
return buf.toString();
}
/**
* Appends the descriptor of the given class to the given string buffer.
*
* @param buf the string buffer to which the descriptor must be appended.
* @param c the class whose descriptor must be computed.
*/
private static void getDescriptor(final StringBuffer buf,
final Class c) {
Class d = c;
while ( true ) {
if ( d.isPrimitive() ) {
char car;
if ( d == Integer.TYPE ) {
car = 'I';
} else if ( d == Void.TYPE ) {
car = 'V';
} else if ( d == Boolean.TYPE ) {
car = 'Z';
} else if ( d == Byte.TYPE ) {
car = 'B';
} else if ( d == Character.TYPE ) {
car = 'C';
} else if ( d == Short.TYPE ) {
car = 'S';
} else if ( d == Double.TYPE ) {
car = 'D';
} else if ( d == Float.TYPE ) {
car = 'F';
} else /* if (d == Long.TYPE) */{
car = 'J';
}
buf.append( car );
return;
} else if ( d.isArray() ) {
buf.append( '[' );
d = d.getComponentType();
} else {
buf.append( 'L' );
final String name = d.getName();
final int len = name.length();
for ( int i = 0; i < len; ++i ) {
final char car = name.charAt( i );
buf.append( car == '.' ? '/' : car );
}
buf.append( ';' );
return;
}
}
}
// ------------------------------------------------------------------------
// Corresponding size and opcodes
// ------------------------------------------------------------------------
/**
* Returns the size of values of this type.
*
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and
* <tt>double</tt>, and 1 otherwise.
*/
public int getSize() {
return (this.sort == Type.LONG || this.sort == Type.DOUBLE ? 2 : 1);
}
/**
* Returns a JVM instruction opcode adapted to this Java type.
*
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
* ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to
* this Java type. For example, if this type is <tt>float</tt> and
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
*/
public int getOpcode(final int opcode) {
if ( opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE ) {
switch ( this.sort ) {
case BOOLEAN :
case BYTE :
return opcode + 5;
case CHAR :
return opcode + 6;
case SHORT :
return opcode + 7;
case INT :
return opcode;
case FLOAT :
return opcode + 2;
case LONG :
return opcode + 1;
case DOUBLE :
return opcode + 3;
// case ARRAY:
// case OBJECT:
default :
return opcode + 4;
}
} else {
switch ( this.sort ) {
case VOID :
return opcode + 5;
case BOOLEAN :
case CHAR :
case BYTE :
case SHORT :
case INT :
return opcode;
case FLOAT :
return opcode + 2;
case LONG :
return opcode + 1;
case DOUBLE :
return opcode + 3;
// case ARRAY:
// case OBJECT:
default :
return opcode + 4;
}
}
}
// ------------------------------------------------------------------------
// Equals, hashCode and toString
// ------------------------------------------------------------------------
/**
* Tests if the given object is equal to this type.
*
* @param o the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type.
*/
public boolean equals(final Object o) {
if ( this == o ) {
return true;
}
if ( o == null || !(o instanceof Type) ) {
return false;
}
final Type t = (Type) o;
if ( this.sort != t.sort ) {
return false;
}
if ( this.sort == Type.OBJECT || this.sort == Type.ARRAY ) {
if ( this.len != t.len ) {
return false;
}
for ( int i = this.off, j = t.off, end = i + this.len; i < end; i++, j++ ) {
if ( this.buf[i] != t.buf[j] ) {
return false;
}
}
}
return true;
}
/**
* Returns a hash code value for this type.
*
* @return a hash code value for this type.
*/
public int hashCode() {
int hc = 13 * this.sort;
if ( this.sort == Type.OBJECT || this.sort == Type.ARRAY ) {
for ( int i = this.off, end = i + this.len; i < end; i++ ) {
hc = 17 * (hc + this.buf[i]);
}
}
return hc;
}
/**
* Returns a string representation of this type.
*
* @return the descriptor of this type.
*/
public String toString() {
return getDescriptor();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -