The Artima Developer Community
Sponsored Link

Java Buzz Forum
Yes, Java fields can be overloaded too

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Vlad Roubtsov

Posts: 20
Nickname: vladr
Registered: May, 2003

Vlad Roubtsov is a Java Q&A columnist for JavaWorld
Yes, Java fields can be overloaded too Posted: Jul 29, 2003 12:33 PM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Vlad Roubtsov.
Original Post: Yes, Java fields can be overloaded too
Feed Title: Java Curiosity Shop
Feed URL: http://www.blog-city.com/bc/
Feed Description: Java esoterics: things from "don't try this at home" category
Latest Java Buzz Posts
Latest Java Buzz Posts by Vlad Roubtsov
Latest Posts From Java Curiosity Shop

Advertisement
A short while ago I needed to add a new method to my .class parsing lib I have been tinkering with for a while. The new method was to lookup a field descriptor from a class definition based on the field name. As soon as I tried to write down the method signature and return type a thought occurred to me: does the name string uniquely specify a class field within its declaring class? For methods the answer is obviously no. As we all know, Java methods can be overloaded (both within the declaring class and across class boundaries). The unique identifier for a method is really a tuple (name, signature). What about Java fields? I was curious enough to dig up the relevant section in the class format specification. The situation turns out to be quite similar to methods, although it can never be exploited at the syntax level. Section 4.5 of the JVM specification says: “No two fields in one class file may have the same name and descriptor” where the field descriptor is the standard type descriptor specified in section 4.3.2 (so, for a long field the descriptor would be “J” and so on). The specification thus does not forbid a class from having more than one field with the same name as long as such fields differ in types. The specification does not explicitly mention this possibility either so I put together a quick test using a Main test driver class (compiled “normally”) and another class X (coded in Java assembly, so I show the javap dump instead): import java.lang.reflect.Field; public class Main { public static void main (final String [] args) throws Exception { Field [] fields = X.class.getFields (); for (int f = 0; f < fields.length; ++ f) { System.out.println (fields [f] + " = " + fields [f].get (null)); } System.out.print ("getting a field by name: "); Field x = X.class.getField ("s_x"); // which field does this get? System.out.println (x); } } // end of class public class X extends java.lang.Object { public static int s_x; public static long s_x; static {}; public X(); } Method static {} 0 iconst_1 1 putstatic #25 <Field int s_x> 4 ldc2_w #17 <Long 2> 7 putstatic #24 <Field long s_x> 10 return Method X() 0 aload_0 1 invokespecial #19 <Method java.lang.Object()> 4 return When I run Main in Sun’s JVM 1.4.1, I get this: public static int X.s_x = 1 public static long X.s_x = 2 getting a field by name: public static int X.s_x So, my X class definition was legal! This is kind of amusing. java.lang.reflect.* API is obviously not prepared to handle all possibilities for a valid class: Class.getField(String) does not take a “fieldType” Class parameter to support proper field lookup by analogy with getMethod(). Note that this is different from field hiding (I could create a class Y that extends X and declares “public static int s_x” again: this is perfectly ordinary and the documentation for getField() lookup algorithm disambiguates this situation). In the above case getField(“s_x”) returned the first field seen in the array returned by getFields(), but this fact cannot be relied on (in fact, the ordering of field descriptors as returned by getFields() is documented to be unspecified). In Sun’s JVMs 1.2.2 and 1.3.1 the results were different: public static int X.s_x = 1 public static long X.s_x = 2 getting a field by name: public static long X.s_x This is just one of those Java curiosities that are possible at bytecode level and not possible at the Java syntax level. Granted, I couldn’t think of any useful way to utilize this field overloading capability at first. But then it dawned on me that it would work well for obfuscation. Given a class, you could rename all of its fields using namespaces that are partitioned by all unique field types found in the class (obviously, along with other things a decent obfuscator would do). Straightforward decompilation of my X.class results in Java source that cannot be recompiled (without field name mangling). Here is the output from jad: public class X { public X() { } public static int s_x = 1; public static long s_x = 2L; } It is quite possible that commercial obfuscators already exploit field overloading. I might check out some of them if I stay curious enough.

Read: Yes, Java fields can be overloaded too

Topic: A Plea for Asian Handset Manufacturers Previous Topic   Next Topic Topic: Motocoder Messes up Again

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use