class JavaClass::ClassFile::JavaClassHeader

Parse and disassemble Java class files, similar to the javap command. Provides all information of a Java class file. This is just a container for all kind of specialised elements. The constuctor parses and creates all contained elements.

See

docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

See

en.wikipedia.org/wiki/Class

Author

Peter Kofler

Attributes

access_flags[R]
attributes[R]
constant_pool[R]
interfaces[R]
magic[R]
references[R]
version[R]

Public Class Methods

new(data) click to toggle source

Create a header with the binary data from the class file.

# File lib/javaclass/classfile/java_class_header.rb, line 40
def initialize(data)
  pos = 0

  #  ClassFile {
  #    u4 magic;
  @magic = ClassMagic.new(data)
  pos += 4

  #    u2 minor_version;
  #    u2 major_version;
  @version = ClassVersion.new(data)
  pos += 4

  #    u2 constant_pool_count;
  #    cp_info constant_pool[constant_pool_count-1];
  @constant_pool = ConstantPool.new(data)
  pos += @constant_pool.size

  #    u2 access_flags;
  @access_flags = ClassAccessFlags.new(data.u2(pos))
  pos += 2

  #    u2 this_class;
  @this_class_idx = data.u2(pos)
  pos += 2

  #    u2 super_class;
  @super_class_idx = data.u2(pos)
  pos += 2

  #    u2 interfaces_count;
  #    u2 interfaces[interfaces_count];
  count = data.u2(pos)
  @interfaces = data.u2rep(count, pos + 2).collect { |i| @constant_pool.class_item(i) }
  pos += 2 + count*2

  #    u2 fields_count;
  #    field_info fields[fields_count];
  @fields = Fields.new(data, pos, @constant_pool)
  pos += @fields.size
  
  #    u2 methods_count;
  #    method_info methods[methods_count];
  @methods = Methods.new(data, pos, @constant_pool)
  pos += @methods.size

  #    u2 attributes_count;
  #    attribute_info attributes[attributes_count];
  attr = Attributes::Attributes.new(data, pos, @constant_pool)
  pos += attr.size
  @attributes =  ClassFileAttributes.new(attr, this_class)
   
  #  }
  @references = References.new(@constant_pool, @this_class_idx)
  
  #  Body {
  # Class: add the byte code sequences to the methods so it can be analysed later (see JVM spec)
  #  }

end

Public Instance Methods

abstract_class?() click to toggle source

Is this class an abstract class (and not an interface)?

# File lib/javaclass/classfile/java_class_header_shortcuts.rb, line 12
def abstract_class?
  access_flags.abstract_class?
end
dump() click to toggle source

Return a debug output of this class that looks similar to javap output.

# File lib/javaclass/classfile/java_class_header.rb, line 119
def dump
  d = []
  mod = @access_flags.public? ? 'public ' : ''
  ext = super_class ? " extends #{super_class.to_classname}" : ''
  int = !@interfaces.empty? ? " implements #{@interfaces.join(',')}" : ''
  d << "#{mod}class #{this_class.to_classname}#{ext}#{int}"
  d << "  SourceFile: \"#{attributes.source_file}\""
  d += @version.dump
  d += @constant_pool.dump
  d << ''
  d << '{'
  d << '}'
  d
end
inner?() click to toggle source
# File lib/javaclass/classfile/java_class_header_shortcuts.rb, line 16
def inner?
  attributes.inner?
end
interface?() click to toggle source

Is this class an interface (and not an annotation)?

# File lib/javaclass/classfile/java_class_header_shortcuts.rb, line 7
def interface?
  access_flags.interface_class?
end
super_class() click to toggle source

Return the name of the superclass of this class or nil. Returns a JavaVMName.

# File lib/javaclass/classfile/java_class_header.rb, line 108
def super_class
  if @super_class_idx > 0
    # This is a ConstantClass entry in the constant pool.
    @constant_pool.class_item(@super_class_idx).class_name
  else
    # special case: java.lang.Object has no superclass
    nil
  end
end
this_class() click to toggle source

Return the name of this class. Returns a JavaVMName.

# File lib/javaclass/classfile/java_class_header.rb, line 102
def this_class
  # This is a ConstantClass entry in the constant pool.
  @jvmname ||= @constant_pool.class_item(@this_class_idx).class_name 
end
to_javaname() click to toggle source

Extend JavaClassHeader to behave like a JavaName in delegating to this_class method which returns a JavaVMName.

# File lib/javaclass/classfile/java_class_header_as_java_name.rb, line 10
def to_javaname
  this_class
end
to_jvmname() click to toggle source
# File lib/javaclass/classfile/java_class_header_as_java_name.rb, line 14
def to_jvmname
  this_class
end
to_s() click to toggle source
# File lib/javaclass/classfile/java_class_header_as_java_name.rb, line 30
def to_s
  to_classname
end