Script; I'm using the rt.jar from Linux, but running on Mac OS X.
Aren't standard file formats great?
#!/usr/bin/perl
use
strict;
my(%fundamental) = ( B => 'byte',
C =>
'char',
S => 'short',
I => 'int',
J => 'long',
F =>
'float',
D => 'double',
Z => 'boolean',
V =>
'void',
);
my(%hitclasses);
while() {
chomp;
if(/^s*Signature:s*(([^)]+))([^()]+)$/i) {
my $argsig=$1;
my
$retsig=$2;
foreach my $sig
($argsig,$retsig) {
my(@types);
my $isArray=0;
while($sig ne '')
{
my
$type=substr($sig,0,1,'');
if($type
eq '[') {
$isArray++;
redo;
}
if($type eq 'L') {
# Class name to ;
my
$class='';
while($sig ne '' and
(my $c=substr($sig,0,1,'')) ne ';') {
$class.=$c;
}
$class=~tr{/}{.};
# print "Found class: $classn";
$hitclasses{$class}++;
} elsif(exists($fundamental{$type})) {
# print "Found fundamental type
$fundamental{$type}n";
} else
{
die "Unknown signature
$type$sign";
}
$isArray=0;
}
}
}
}
foreach my $class (sort(keys(%hitclasses))) {
next if grep { $class =~ /^Q$_E./ } @ARGV;
print
$class,"n";
}
Command line... I use Z shell, so yes, command
line includes newlines....
zipinfo -1 rt.jar java/lang/* java/io/*
java/util/* |
tr / . | sed -e 's/.class$//' |
while read class;
do
javap -classpath rt.jar $class -s
done | perl ./parse-signature
java.lang java.util java.io
[ Reply to This | Parent | # ]
|
There is a programming concept called separation of concern. The reality is
that in implementing code, common functionality is factored out, so
that it
resides in one place, simplifying debugging and maintenance at the cost
of some
speed. (Some compilers will inline some functions, that is have the
machine
language be executed sequentially without jumps to other parts of the
program.
A jump to a function requires overhead as a new stack is started for
the
function's use and then destroyed when the function is finished. The
compiled
program is larger as the lines required to execute the function are
copied and
replace the one line that called the function, but the program runs
faster.) Sun also did some
major plumbing work in order to speed up the
execution of programs. The nio
package was designed for faster i/o. But
rewriting the java.io package would
break existing programs, so nio was added
to the language and Sun's objects
that called io inside the implementations
were switched to nio instead.
One has
to keep in mind that Sun wrote the
jvm to run on multiple operating systems. At
some point, the jvm has to talk to
the hardware and that is through the
operating system. Private classes, tuned
to the specific operating system,
subclass abstract classes. But, being
private, the programmer is not able to
access
these classes, which is partly a
security feature and partly an aide to
compatibility across platforms. As
an example, there is a java.io.File
object constructor that take a File object
(for the folder) and a String for the file
name. Let's say we make a File
object in my home directory. File f = new
File(homeDirectory,"example.txt"); Now if I call f.getAbsolutePath(), I will
see "/Users/dano/example.txt" on my Mac. If the same code ran on Windows, I
would see "C:Usersdanoexample.txt". The use of '/' or '' is a detail that
has
to be implemented by some code somewhere which understands exactly what
operating system it is running on. That code is not public, by which I mean
that
I, a programmer restricted to the public api, cannot write code that
changes the
answer. However, because the File constructor does the right thing,
as far as I'm
concerned, the os is abstracted away from my programs. (Though,
the *nixes
call
the home directory HOME, but HOME is not defined in Windows.
If I want the
home directory, I use USERPROFILE form
System.getenv().getProperty().
Java is an Object Oriented language. A
main
concept is one called encapsulation, direct ability to access and mutate
values is
discouraged. Here's another taste of java. A class is a file
that provides
the instructions for creating like items, called objects and also
called an
instance of the class. For instance, we may have a GroklawMember
class which
defines instance values such as String memberName, String
identifyingEmail,
Date dateJoined, String password. The object is supposed to
protect its instance
values. That is, some information is not to be shared and
some information is
not to be changed, except that the conditions for change
are correct. The
password seems like a good thing for the objects to keep
confidential, so we
wouldn't implement a String getPassword() method if we can
avoid it, because
that allows any other object in scope (processor memory) to
know what that
GroklawMember instance's password is. Since we do have to check
passwords,
we might create a
method: boolean isCorrectPassword(String
enteredPassword) which would
compare the parameter enteredPassword to the
object's internal password
value. If a match, true, if not, false. If we want
to allow passwords to change, we
would implement a method like this: boolean
changePassword(String
oldPassword, String newPassword) { if
(isCorrectPassword(oldPassword)) {
this.password = newPassword; return true; }
else return false; }. Using this
design, the outside world, even as it uses the
password for verifications, does
not
get to know what the password is. That's
an example of encapsulation.
Note: I
have glossed over the step where
that new password is persisted, i.e., saved to
a file. Me, I would have a
MemberStore object and put the concerns of
reading and writing to the file
system there. The point of my little java
diversion is that the instance
values in an object are indirectly referenced or
shielded. For instance, above,
the password could not be changed except the a
password matching the old one
was provided. I could have added a check, for
instance the new password had to
have a certain length, or could not have been
one already used, or has to have
a punctuation mark. The point being that the
instance value of the password is
externally changed through the method, not
directly, and if the conditions we
think are necessary are not met, the object
refuses to make the change.
Similarly, implementation details are hidden from the programmer using the
public interface. Incidentally, one of the things we expect from the
maintainers
of a programming language is that they are very careful and public
about what
they change in the language and any public libraries (which is what
I'd call the
apis) provided as part of the
language. They are free to change
the private apis and this they do, as they
work out
improvements or decide
that something is not needed. On a tangent, one of the
things that will get a
iOS developer's app rejected is use of Apple's private apis.
While a cynic may
say Apple is reserving the good stuff for themselves,
it is also a part of its
frameworks that Apple feels free
to change without notice. If one uses a
private api and Apple does change it, the
app will crash, which will irritate
the customers, so good developers resist that
temptation. Returning to
Android, we should keep in mind that dalvik is talking to Google's operating
system and, so the implementation at the metal is simpler than java's, which
has to, as seamlessly as possible, talk to Windows, Solaris, Linux, AIX,
FreeBSD,
etc. As it wrote its language, Google could put implementation
functionality within the implementation of the publicly known method or in
private methods which are invisible to the programmer using the api. Being
smart programmers, Google did refactor, separated concerns, and wrote private
classes and packages. Also since the java.nio package was Sun taking a
mulligan with java.io, in some sense one could say that that should have been
the way Sun implemented java.io back in the mid-90s. I make that point
because
Google (as did Microsoft with .net) probably learned from Sun's
mistakes and
made their java.io efficient. Honest answers to questions
6-8 certainly
undercut Oracle's suggestion that looking up the packages, classes, methods
and signatures in documentation to java solves a lot of the problems Google
had as they built the app side of the Android platform.
Using the same
names and signatures solves one key problem: existing java
source
code won't
run except there are matching names. (Well, there is another way: if
there is a
one-to-one match between a java name and a dalvik name, an
intermediate step to
translate java code to d-code would solve compatibility.
Still, there has to be
a precise match where compatibility is supported, so what
would be the point?)
That would be one problem among tens of thousands to
be solved as
they brought
a limited java source code compatibility feature to the many
features
exposed
through the full api of the Android platform. But, it has to be said, that
limited java source code compatibility was an option and a choice made to
improve the viability of the nascent Android platform. A feature
on the check
list Google circulated to phone manufacturers: developers who
knew
how to
write the apps were easily found and some of the apps were already
written. It
wasn't necessary — iOS and Windows Phone ignore java — but it was
an attraction
to the phone manufacturers who wanted to get in the game that
Apple had changed
with the iPhone. [ Reply to This | Parent | # ]
|