As mentioned in the other answers, there is nothing really like a category. I do have some common solutions I use for some of the categories in my objective-c code when porting over to java. Many of my objective-c categories exist because I don't want to extend the iOS base classes but I do want to add some functionality to that class. Many of those objective-c categories do not add properties using objc_SetAssociatedObject. For those cases I use a static helper class in Java. Let's look at an example using NSString and String. I will add functionality to both to add quotes to the string. We'll assume this is useful and does not exist for the purposes of illustration. In objective-c we might have:
@interface NSString (MyCategory)
/**
* Creates and autoreleased image from self.
*/
- (NSString*)quotedString;
@end
@implementation NSString (MyCategory)
- (NSString *)quotedString
{
return [NSString stringWithFormat:@"\"%@\"", self];
}
@end
You would call this from somewhere like this:
NSString *myString = @"When you're curious, you find lots of interesting things to do.";
NSString *quotedString = [myString quotedString];
Here's how I would implement this in Java:
public class StringHelper {
public static String quotedString(String that) {
return '"' + that + '"';
}
}
And to call it:
String myString = = "When you're curious, you find lots of interesting things to do.";
String quotedString = StringHelper.quotedString(myString);
If you think of the category methods as methods that automatically send the self variable as the first method argument (albeit invisible) then this makes even more sense.
For your example, if I would not extend the specific object, I might do something like:
public class ObjectHelper {
public static void printDetail(Object that) {
// do what it takes;
}
}
UPDATE: A commenter asked for limitations.
Limitations would be that the code is in a separate static class. It's not as convenient as a category. You have to remember those class names, or find them, and you will not get auto completion on your original objects methods in the helper. Also, you cannot use object level properties or attributes like you get with objc_SetAssociatedObject. You could use a hash map and create something similar with the original object instance as a hash key.
public class StringHelper {
private static Map<String, Integer> order = new HashMap();
public static int getOrder(String that) {
if(that == null) { return 0; }
Integer ret = StringHelper.order.get(that);
if(ret == null) { return 0; }
else { return ret; }
}
public static void setOrder(String that, int order) {
if(that != null) {
StringHelper.order.put(that, order);
}
}
}
There are also no name clashes with the original class, which would be more of a benefit. Name clashes in objective-c categories are considered bad.