In Javassist, is return order guaranteed? - java

Javassist's CtClass has a few methods, such as getFields() and getMethods(). I was wondering if these methods offer any guarantee as to their ordering.
Specifically, I'd like to know if using getFields() on a class will produce and array of CtFields where the first field in the array is the first field declared in the file and so forth. So, is this order guaranteed? If not, is there anything that can offer this guarantee? The javadocs give no information on the matter. I've tried annotations that carry order (e.g. #X(1) private int first;), but it'd be easier if I could reflect this sort of thing without the need for annotations?
If it's still not clear, I'd like something like:
public class Class {
public int x;
public float y;
public Object z;
}
to produce an array of CtFields specifically and consistently ordered x, y, z.

If you look at one of the implementations of CtClass, like CtClassType, you will see that getMethods() is implemented that way:
public CtMethod[] getMethods() {
HashMap h = new HashMap();
getMethods0(h, this);
return (CtMethod[])h.values().toArray(new CtMethod[h.size()]);
}
According to the HashMap javadoc:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
So, you have absolutely no guarantee in what order you will get the methods.
For the fields, the code is a lot more complicated, but it seems that the raw class file is read as an InputStream:
DataInputStream in = new DataInputStream(
new FileInputStream(args[0]));
ClassFile w = new ClassFile(in);
And the fields are created as they are read from this stream:
fields = new ArrayList();
for (i = 0; i < n; ++i)
addField2(new FieldInfo(cp, in));
So, the fields are created in the order they are in the class file.
However, reading the JVM Specification and the Java Language Specification, I see no reference to the fields order in the generated class; this sentence from the Java Specification even seems to indicate that the fields order is not important:
Using their scheme, here is a list of some important binary compatible changes that the Java programming language supports:
[...]
Reordering the fields, methods, or constructors in an existing type declaration.
So I think that you have absolutely no guarantee on the fields order too.
I tried to run javassist.tools.Dump on a test class I created with a large number of fields and methods, and it seems that fields and methods are printed in the source order, but I still think that nothing guarantee it.

Related

Why does the instance method `hashCode` on `java.lang.Integer` make an extra jump to the static class method to simply return its own integer value?

I was just exploring different kinds of implementations to the hashCode() method. I opened up the java.lang.Integer class and found this implementation for hashCode():
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
My question is, why can't the implementation be as simple as:
public int hashCode(){
return this.value;
}
What is the need to create an additional static method to pass around the value and return the same? Am I overlooking any important detail here?
That code does look odd when viewed on its own.
But notice that the static method java.lang.Integer.hashCode:
was added later, in Java 8
is public
The source code in Java 14 shows no comments to explain why this static method was added. Because the method is public, I presume this new static method plays a part in some new feature in Java 8, perhaps related to streams, called elsewhere in the OpenJDK codebase.
As noted in the Javadoc, the source code of the existing Integer::hashCode instance method was rewritten to call the static hashCode simply for consistency. This way there is only one place where the hash code is actually being generated. Having only one place is wise for review and maintenance of the codebase.
Making hashCode static is certainly unusual. The purpose of the hashCode method is to identify one object of that class to another for use in collections such as HashSet or HashMap. Given that we are comparing instances by the method, it makes sense for hashCode to be an instance method rather than static.
The optimizing compiler such as HotSpot or OpenJ9 is likely to inline the hashCode method calls, making moot the instance-method versus static-method arrangement in source code.
#Basil Bourque's answer covers just about everything. But he leaves open the question of why the public static void hashCode(int) was added.
The change was made in this changeset in November 2012
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/be1fb42ef696/src/share/classes/java/lang/Integer.java
The title and summary for the changeset say this:
7088913: Add compatible static hashCode(primitive) to primitive wrapper classes
Summary: Adds static utility methods to each primitive wrapper class to allow calculation of a hashCode value from an unboxed primitive.
Note that the changeset does not document the motivation for the change.
I infer that one purpose of the enhancement is to avoid the application programmer having to know how the primitive wrapper classes are computed. Prior to Java 8, to compute the wrapper-compatible hash code for a primitive int, the programmer would have to have written either
int value = ...
int hash = ((Integer) value).hashCode(); // Facially inefficient (depending on
// JIT compiler's ability to get
// rid of the box/unbox sequence)
or
int value = ...
int hash = value; // Hardwires knowledge of how
// Integer.hashCode() is computed.
While the "knowledge" is trivial for int / Integer, consider the case of double / Double where the hash code computation is:
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
It seems likely that this changeset was also motivated by the Streams project; e.g. so that Integer::hashCode can be used in a stream of integers.
However, the changeset that added sum, min and max for use in stream reductions happened a couple of months after this one. So we cannot definitively make the connection ... based on this evidence.

What is meant by property in java ?

Does it differ from methods? Like arrays have a property - length and so array.length gives the length of array whereas array.length() gives an error
A better term to use for properties is a field. Basically, a field is a variable, while a method is where you have the "meat" of your code. For these examples, I'll be using the object "Book".
Fields can be classified as "instance" variables meaning that they are different for each object, or they can be classified as "static" variables, which means that they are universal for the project.
private int pages;
private static int amountOfBooksInTheWorld;
The number of pages is specific to a certain book, a specific "instance" of the book object. The amount of books in the world is obviously not specific to one book; therefore, it is "static", universal, for all books. Instance variables are called by stating objectname.variablename, while static variables are called by classname.variablename.
javahandbook.pages
Book.amountOfBooksInTheWorld
Now for your second question, methods, those things with the parentheses, are usually classified into these groups: constructor, accessor, mutator, and static methods. All methods have "parameters" and "return types". The parameters are basically inputs. The return types are the outputs (if there are any). Methods are called by objectname.method(), unless they are static, where they are called by classname.method().
Constructors are what you use to create your object. They usually are the ones which "initialize" all the instance variables for the object, that is to say, they basically tell them what they start as. These methods have no return type. Constructors are probably the most different method type from the rest, but are very important.
public Book(int p) {
pages = p; //We use "=" to initialize our variables (left becomes the right)
}
In action...
Book javahandbook = new Book(100); //A new book has been created!
Accessor methods are what other classes use to find out what are the instance variables of a particular object. These specify a return type of either boolean (a fancy name for true or false), floating point numbers (double-precise return types that include double and float), regular numbers (integer return types such as byte, short, int, or long), or even other objects. The return type is what you get "back" when the method is done doing its thing. Keep in mind that the object being referred to in the method call is the "implicit parameter", meaning that it can be referred to using "this". It sounds wierd. I'll show you an example.
public int getPages() {
return (this.pages);
}
In action...
int test = javahandbook.getPages();
System.out.println(test); //This will return the amount of pages
//Note that what I did with the 2nd line was bad coding practice, but it works in this scenario
Mutator methods change the instance variables. Their return type is "void".
public void ripPages(int rippedpages) {
this.pages = this.pages - rippedpages;
System.out.println("HULK SMASH");
}
In action...
javahandbook.ripPages(300);
Static methods are the ones that are universal, not on a per object basis. They can have any return type.
public static int countBooks(List<Book> books) {
return (books.size);
}
In action...
public int howmanybooksinthislist = Book.countBooks;
Put all of them together and you get...
public class Book {
private int pages;
private static int amountOfBooksInTheWorld;
public Book(int p) {
pages = p;
}
public int getPages() {
return (this.pages);
}
public void ripPages(int rippedpages) {
this.pages = this.pages - rippedpages;
System.out.println("HULK SMASH");
}
public static int countBooks(List<Book> books) {
return (books.size);
}
I know this was a bit too lengthy, but I hope it helps!
Properties/Fields are variables in a class. For example:
public class Employee {
private String name;
private int salary;
public getName(){return this.name};
}
In the class above, name and salary are properties of an instance of the class (object of the class) while getName() is a method.
Properties are the adjectives describing an object, in this example "how many elements it has". Properties are set to define variable aspects of instance of the object, either directly (if allowed) or as the result of some action, and then they may be examined when using the object.
Methods are the verbs provided to do something with the object, for example "add a new element". These actions may utilize properties, and may alter them, as well as doing other things (whatever purpose the creator defines). Methods may also accept adverbs in the parenthesis that further effect how they operate, thus the different syntax with "()"; for example information to "add in the new element".
While methods are more complex and versatile mechanisms, a complex object might not have pre-calculated (cached) "x.length" type properties always already available to examine and thus the object might provide a method "x.length()" to get the information. That method might have to evaluate complex aspects of an object to figure out "length", and either set it and or give it back, blurring the line between a property and that more simple use of a method.
Tangent on "field", "property" and "properties": while the technical term "field" very specifically identifies a data storage element attached to an object, the term "property" is acknowledged by the core group at http://docs.oracle.com/javase/tutorial/information/glossary.html. A property is more abstract, but logically synonymous to field when considered in comparison to a method. Logically different than field/property in this comparison, though related, is a "properties" set which is a static gathering of initial settings of property values for an application (a collection of code presented for a designated use), most often placed in a file ".properties" named and stored at a location agreed upon by the application - though these might also be gathered in any other storage location like a database.
array.length is accessing a field inside the object, while array.length() is attempting call a method call length(), and since the method does not exist, it gives an error
To understand properties and methods, think of an apple. An apple can be different colours, like red, yellow, etc. An apple can also have varying sizes. Both of these traits, colour and size, are properties of an individual apple; they describe the apple.
A method is different. It describes something an apple can do, like grow and ripen. Some methods, however, can also represent properties, and simplify reading those properties.
For example, an object representing a pen might have a certain amount of ink left. When requesting how much ink is left, the pen object would need to verify that there is any, and refill the pen if not, before returning how much ink there is.
To directly answer your question, properties and methods are very different. Properties hold data about an object, but methods hold data about what an object can do. Something like the length of an array is a property because it describes the array itself, not what the array can do.
This and other definitions of some useful terms are given here.

Best strategies when calling a method that should modify more than one variable

I am pretty new to Java, I have to convert C/C++ code to Java and I am running into obstacles. Because of the way variables are passed to the methods, their modification in the method is not straightforward, and I have no idea what is the most reasonable approach to take. Sorry for the pseudocode examples, I hope they will clearly explain what I am talking about without delving into unnecessary details.
I need something that would be equivalent to C
ModifyMyString(type1 &t1,type2 &t2);
(return type doesn't matter, it can be void) as I need the function to modify both t1 and t2.
I can easily modify one of the variables, say t1, by declaring in Java
type1 modifyMyString(type1 t1, type2 t2);
and assigning the returned value to
t1 = modifyMyString(t1,t2);
but it is only half of a success, as the new value of t2 is lost.
I can declare new class
class JustToPassTwoVariables {
type1 t1;
type2 t2;
JustToPassTwoVariables(type1 tt1, type2 tt2) { t1 = tt1; t2 = tt2; }
}
and do something like
JustToPassTwoVariables jtptv = modifyMyString(JustToPassTwoVariables(t1,t2));
but I feel like it is clumsy and makes the code unreadable.
In desperation I could also resign the idea of using a modifyMyString method, and repeat all the code locally in each place I would call modifyMyString - but it makes even less sense than using JustToPassTwoVariables class.
Is there a correct (or at least widely used, accepted as a standard, whatever) strategy to code such things in Java?
The recommended way in java is (in some people's opinion the clumsy way) to create a class containing the two fields and return an instance of that class.
I feel that it is much less clumsy if you stop and think about what the method is actually doing, and taking care to properly name both the method and the class returning the two values.
The simple answer is no. This sort of feature is not allowed in Java.
The correct way to do it is to pass in the object to be modified not the two variables. After all in virtually all cases those variables are already wrapped in an object, in cases where they aren't they often easily can be.
Either split the function into two functions and call it once for each variable, or wrap the variables into an object and pass that object into the function.
Don't forget Java allows Inner Classes which makes this sort of thing less painful.
You can't return two values from a method in java. The way is to return an object and set all the values in it. i.e. In your case, you need to create a value container class i.e. say Result class that will have two fields storing the type1 and type2 value in it. The return type of the method would be of value container object type i.e. say Result instance with two fields in it - type1 and type2
Example :
Result result = modifyMyString(t1,t2);
result.getT1(); //gets t1 value
result.getT2(); // gets t2 value
Please learn about setters and getters in Java to work on the class or object level fields
In Java if you want to do this you would generally make type1 and type2 into object whose values can be modified. The method can then modify the values of the parameters to get the desired effect. For example :
void myMethod(type1 arg0, type2 arg1) {
arg0.setValue(newValue0);
arg1.setValue(newValue1);
}
If type1 and/or type2 do not have any way of changing their values (e.g. they are of type String) then you would either make a wrapper class for each of them e.g.
class Type1Wrapper {
private type1 type1;
type1 getType1() {
return type1;
}
void setType1(type1 newType1) {
type1 = newType1;
}
}
or you would make a wrapper for both of the types simultaneously like you have in your question (although the method return type will be void and the method will modify your wrapper's values)
There are several methods to modify a group of objects "of the same type/class". The simplest of them being, add them to a "list" pass that list to your modification function, do whatever modifications/additions/deletions etc.. The list reference will be automatically available outside with the "changes made in the called function" .
So, you can do
List<String> l = new ArrayList<String>();
l.add("Hello");
l.add("world");
ModifyMyString(l);
// here also l = "hello" , "world" , "added"
public void ModifyMyString(List l)
{
l.add("added"); // now l = "hello" , "world" , "added"
}
Java is an OO language so to get the best out of it you should look to an OO solution. It's hard to give you a definite solution with this abstract example but this is how I would approach this.
You mention that t1 and t2 both need to be updated by this modify procedure/method. Also that they need to be updated at the same time, if they were unrelated then you could just call modify on each string in turn. If these two strings are related like this then it's likely they belong to the same type.
So we need a class containing type 1 and type 2.
public class TypeContainer
{
private String type1;
private String type2;
.. getters and setters
}
Obviously you'll want a better class name.
You suggest something similar yourself but call it JustToPassTwoVariables. This is missing the point of OO. You could write a simple wrapper like this and pass it to some other method to modify the values but a more OO approach would be to add the modify method to this class itself.
...
public void modfiy(String val1, String val2)
{
type1 = val1;
type2 = val2;
}
...
I'm not sure what your modify is trying to do but in this case I would probably have these as two separate setter methods. This is quite an abstract example!
Basically I would avoid having the modify method in some other unrelated class. You should look to group common related attributes into classes and then write methods in those classes for any actions you need to take (such as modify).
Trying to convert a procedural C program into an OO Java program sounds like a PITA. It's a complete paradigm shift. Having said that I have seen automated conversions which while technically Java are still very procedural. Not very pretty and hard to maintain but was done for political reasons.
Java discourages this strategy beacause in-variable should be immutable, but if you have to migrate from C/C++/C# and you have a lot of "void function with parameters passed as in/out", you can create a Custom "Reference" class like this and you can incapsulate the original object.
public class CustomRef {
public Object internal;
public CustomRef(Object object) {
this.internal=object;
}
}
then when you call
CustomRef ref1= new CustomRef(myParams1);
CustomRef ref2= new CustomRef(myParams2);
myFunction(ref1, ref2);
myParams1 = ref1.internal;
myParams2 = ref2.internal;
the function is
void myFunction(CustomRef ref1, CustomRef ref2) {
Object param1 = ref1.internal
// a lot of code
ref1.internal = param1;
}
really discouraged way ... such as using ArrayList, arrays [] to "pass by reference".
NOTE: this way is a waste of resource; CustomRef instance should be reused through object pool (another discouraged way).
I would use a StringBuffer. You can initialize it with a String and convert it back to a String

Java replacement for C macros

Recently I refactored the code of a 3rd party hash function from C++ to C. The process was relatively painless, with only a few changes of note. Now I want to write the same function in Java and I came upon a slight issue.
In the C/C++ code there is a C preprocessor macro that takes a few integer variables names as arguments and performs a bunch of bitwise operations with their contents and a few constants. That macro is used in several different places, therefore its presence avoids a fair bit of code duplication.
In Java, however, there is no equivalent for the C preprocessor. There is also no way to affect any basic type passed as an argument to a method - even autoboxing produces immutable objects. Coupled with the fact that Java methods return a single value, I can't seem to find a simple way to rewrite the macro.
Avenues that I considered:
Expand the macro by hand everywhere: It would work, but the code duplication could make things interesting in the long run.
Write a method that returns an array: This would also work, but it would repeatedly result into code like this:
long tmp[] = bitops(k, l, m, x, y, z);
k = tmp[0];
l = tmp[1];
m = tmp[2];
x = tmp[3];
y = tmp[4];
z = tmp[5];
Write a method that takes an array as an argument: This would mean that all variable names would be reduced to array element references - it would be rather hard to keep track of which index corresponds to which variable.
Create a separate class e.g. State with public fields of the appropriate type and use that as an argument to a method: This is my current solution. It allows the method to alter the variables, while still keeping their names. It has the disadvantage, however, that the State class will get more and more complex, as more macros and variables are added, in order to avoid copying values back and forth among different State objects.
How would you rewrite such a C macro in Java? Is there a more appropriate way to deal with this, using the facilities provided by the standard Java 6 Development Kit (i.e. without 3rd party libraries or a separate preprocessor)?
Option 3, create you own MutableInteger wrapper class.
struct MutableInteger{
public MutableInteger(int v) { this.value = value;}
public int value;
}
public void swap3( MutableInteger k, MutableInteger l, MutableInteger m) {
int t = m.value;
m.value = l.value
l.value=k.value;
k.value=t;
}
Create a separate class e.g. State
with public fields of the appropriate
type and use that as an argument to a
method
This, but as an intermediate step. Then continue refactoring - ideally class State should have private fields. Replace the macros with methods to update this state. Then replace all the rest of your code with methods that update the state, until eventually your program looks like:
System.out.println(State(System.in).hexDigest());
Finally, rename State to SHA1 or whatever ;-)

How do I pass a primitive data type by reference?

How can I pass a primitive type by reference in java? For instance, how do I make an int passed to a method modifiable?
There isn't a way to pass a primitive directly by reference in Java.
A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:
public class IntRef { public int value; }
But how about some pre-built wrapper classes, so we don't have to write our own? OK:
The Apache commons-lang Mutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
The java.util.concurrent.atomic Atomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.
Length 1 primitive array
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?
Also see
The answers to StackOverflow question "Mutable boolean field in Java".
My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.
Nothing in java is passed by reference. It's all passed by value.
Edit: Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:
String a;
int b;
doSomething(a, b);
...
public void doSomething(String myA, int myB) {
// whatever I do to "myA" and "myB" here will never ever ever change
// the "a" and "b"
}
The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.
With a holder:
private class MyStringHolder {
String a;
MyStringHolder(String a) {
this.a = a;
}
}
MyStringHolder holdA = new MyStringHolder("something");
public void doSomething(MyStringHolder holder) {
// alter holder.a here and it changes.
}
With return value
int b = 42;
b = doSomething(b);
public int doSomething(int b) {
return b + 1;
}
Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short> if necessary too.
Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).
That's not possible in Java, as an alternative you can wrap it in a single element array.
void demo() {
int [] a = { 0 };
increment ( a )
}
void increment( int [] v ) {
v[0]++;
}
But there are always better options.
You can't. But you can return an integer which is a modified value
int i = 0;
i = doSomething(i);
If you are passing in more than one you may wish to create a Data Transfer Object (a class specifically to contain a set of variables which can be passed to classes).
Pass an object that has that value as a field.
That's not possible in Java
One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.
On the other hand, you can just use code like:
int a = 5;
a = func(a);
and have func return the modified value.

Categories

Resources