CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2005
    Location
    Currently in Mexico City
    Posts
    568

    Question about inheritance in Java

    I am writing a small bean manager and I was wondering if it is possible to extend Object class to make new methods apply to my beans without having each bean implement my extended class.

    for example I have a fieldset copying method which scans source and target beans for similar fields and types and copies values from one bean to the other:
    Code:
    public static Object map(Object beanA, Object beanB) {
      Class<?> classA = beanA.getClass();
      Class<?> classB = beanB.getClass();
      Field[] fieldsetA = classA.getDeclaredFields();
      Field[] fieldsetB = classB.getDeclaredFields();
      try {
        for (Field fieldA : fieldsetA) {
          for (Field fieldB : fieldsetB) {
            if (fieldA.getName().equals(fieldB.getName()) && fieldA.getType() == fieldB.getType()) {
              String setterName = "set" + capitalize(fieldB.getName());
              String getterName = (fieldA.getType().getName().equals("boolean") ? "is" : "get") + capitalize(fieldA.getName());
              Method getter = classA.getDeclaredMethod(getterName);
              Method setter = classB.getDeclaredMethod(setterName, fieldB.getType());
              setter.invoke(beanB, getter.invoke(beanA));
            }
          }
        }
      } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace(System.out);
      }
      return beanB;
    }
    So later I use:
    Code:
    beanB = (BeanB)map(beanA,beanB);
    It works. Still what I would like is to be able to apply map method to a bean2 object directly without needs of casting and mentioning bean2 twice. Something like this:
    Code:
    beanB.map(beanA);
    Is it possible without implementing my extended class in every bean explicitly? Or have I recompile the JDK Object class and use my own JDK distro?
    Last edited by Xeel; October 7th, 2009 at 04:46 PM.
    Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?

    I had a nightmare last night. I was dreaming that I’m 64-bit and my blanket is 32-bit and I couldn’t cover myself with it, so I’ve spent the whole night freezing. And in the morning I find that my blanket just had fallen off the bed. =S (from: bash.org.ru)

    //always looking for job opportunities in AU/NZ/US/CA/Europe :P
    willCodeForFood(Arrays.asList("Java","PHP","C++","bash","Assembler","XML","XHTML","CSS","JS","PL/SQL"));

    USE [code] TAGS! Read this FAQ if you are new here. If this post was helpful, please rate it!

  2. #2
    Join Date
    Oct 2008
    Posts
    77

    Re: Question about inheritance in Java

    wow, talk about ugly solutions, "Recompiling the SDK", do you want all your users to do so too??

    Often, answer is very simple:

    Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.
    http://java.sun.com/docs/books/tutor...ubclasses.html

  3. #3
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Question about inheritance in Java

    You can generify the method to avoid the BeanB cast, but I don't see how you can avoid passing a beanB instance, because you need an instance of BeanB in the method and you can't create an instance of a parameterized type (beanB) inside the method.

    Here's the generified version:
    Code:
    public static <A, B> B map(A beanA, B beanB) {
        Class<A> classA = (Class<A>) beanA.getClass();
        Class<B> classB = (Class<B>) beanB.getClass();
        Field[] fieldsetA = classA.getDeclaredFields();
        Field[] fieldsetB = classB.getDeclaredFields();
        try {
            for (Field fieldA : fieldsetA) {
                for (Field fieldB : fieldsetB) {
                    if (fieldA.getName().equals(fieldB.getName()) && fieldA.getType() == fieldB.getType()) {
                        String setterName = "set" + capitalize(fieldB.getName());
                        String getterName = (fieldA.getType().getName().equals("boolean") ? "is" : "get") +
                                            capitalize(fieldA.getName());
                        Method getter = classA.getDeclaredMethod(getterName);
                        Method setter = classB.getDeclaredMethod(setterName, fieldB.getType());
                        setter.invoke(beanB, getter.invoke(beanA));
                    }
                }
            }
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace(System.out);
        }
        return beanB;
    }
    ...
    beanB = map(beanA, beanB);
    Alternatively, if you have all your beans subclass a mapper class you can do what you wanted:
    Code:
    class Mapper {
        public void map(Mapper beanA) {
            Class classA = beanA.getClass();
            Class classB = getClass();
            Field[] fieldsetA = classA.getDeclaredFields();
            Field[] fieldsetB = classB.getDeclaredFields();
            try {
                for (Field fieldA : fieldsetA) {
                    for (Field fieldB : fieldsetB) {
                        if (fieldA.getName().equals(fieldB.getName()) && fieldA.getType() == fieldB.getType()) {
                            String setterName = "set" + capitalize(fieldB.getName());
                            String getterName = (fieldA.getType().getName().equals("boolean") ? "is" : "get") +
                                                capitalize(fieldA.getName());
                            Method getter = classA.getDeclaredMethod(getterName);
                            Method setter = classB.getDeclaredMethod(setterName, fieldB.getType());
                            setter.invoke(this, getter.invoke(beanA));
                        }
                    }
                }
            }
            catch (Exception e) {
                System.out.println(e.getMessage());
                e.printStackTrace(System.out);
            }
        }
    }
    ...
    class BeanA extends Mapper { ... }
    class BeanB extends Mapper { ... }
    ...
    beanB.map(beanA);
    This does have the advantage of only allowing Mapper beans to participate.

    As soon as we started programming, we found out to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs...
    M. Wilkes
    Last edited by dlorde; October 8th, 2009 at 09:11 AM.
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  4. #4
    Join Date
    Jul 2005
    Location
    Currently in Mexico City
    Posts
    568

    Re: Question about inheritance in Java

    Quote Originally Posted by postmortem View Post
    wow, talk about ugly solutions, "Recompiling the SDK", do you want all your users to do so too??

    Often, answer is very simple...
    Knew this from the very first day I started coding in Java... That's why I was talking about Object extension. Also I am not crazy to recompile SDK . I just was asking if it's the only real solution for my "problem". And as I understand it is btw.

    Btw theoretically speaking SDK recompilation is not insane solution in cases of a single enterprise web application. These are rarely if ever updated and it's applications server per app. So practically anything can be customized there. The real insanity applies in cases of applets and desktop applications only.

    Quote Originally Posted by dlorde
    Here's the generified version...
    Thanks, really! I almost forgot you could do it this way (rarely use generics these days ). As for the inheritance, well, nevermind... I just was hoping for some super-wonder modern technique to globally override classes or something... I wasn't sure such thing existed anyways. Just checking, you know...

    Thanks guys, you clearly showed me the way out of the weed room.
    Last edited by Xeel; October 8th, 2009 at 10:14 AM.
    Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?

    I had a nightmare last night. I was dreaming that I’m 64-bit and my blanket is 32-bit and I couldn’t cover myself with it, so I’ve spent the whole night freezing. And in the morning I find that my blanket just had fallen off the bed. =S (from: bash.org.ru)

    //always looking for job opportunities in AU/NZ/US/CA/Europe :P
    willCodeForFood(Arrays.asList("Java","PHP","C++","bash","Assembler","XML","XHTML","CSS","JS","PL/SQL"));

    USE [code] TAGS! Read this FAQ if you are new here. If this post was helpful, please rate it!

  5. #5
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Question about inheritance in Java

    Quote Originally Posted by Xeel View Post
    I just was hoping for some super-wonder modern technique to globally override classes or something... I wasn't sure such thing existed anyways. Just checking, you know...
    You might be able to get closer with AOP (Aspect Oriented Programming), but it's been a while since I looked at it, so you'd have to do some reading.

    Never hesitate to ask a lesser person...
    Confucius
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  6. #6
    Join Date
    Jul 2005
    Location
    Currently in Mexico City
    Posts
    568

    Re: Question about inheritance in Java

    A similar but more complicated one:
    I am having real trouble writing a List copying method:
    PHP Code:
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;

    public class BeanMapper {

        public static <A, B> B map(A beanA, B beanB) {
            Class<?> classA = beanA.getClass();
            Class<?> classB = beanB.getClass();
            Field[] fieldsetA = classA.getDeclaredFields();
            Field[] fieldsetB = classB.getDeclaredFields();
            try {
                for (Field fieldA : fieldsetA) {
                    for (Field fieldB : fieldsetB) {
                        if (fieldA.getName().equals(fieldB.getName())
                                && fieldA.getType() == fieldB.getType()) {
                            String setterName = "set" + capitalize(fieldB.getName());
                            String getterName = (fieldA.getType().getName().equals("boolean") ? "is" : "get") + capitalize(fieldA.getName());
                            Method getter = classA.getDeclaredMethod(getterName);
                            Method setter = classB.getDeclaredMethod(setterName, fieldB.getType());
                            setter.invoke(beanB, getter.invoke(beanA));
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
                e.printStackTrace(System.out);
            }
            return beanB;
        }
        
        public static <A,B> ArrayList<B> mapList(List<A> listA, B itemB){
            ArrayList<B> listB = new ArrayList<B>();
            BeanMapper bm = new BeanMapper();
            for(A itemA : listA){
                ClassFactory<B> instance = bm.new ClassFactory<B>();
                itemB = instance.get();
                itemB = map(itemA,itemB);
                listB.add(itemB);
            }
            return listB;
        }
        

        private static String capitalize(String word) {
            return word.substring(0, 1).toUpperCase() + word.substring(1);
        }
        
        private class ClassFactory<T> {
            private T instance;
            public T get(){
                return instance;
            }
        }
    }
    When I run it I get NullPointerException in line 22 (Class<?> classB = beanB.getClass();). Why instance.get() from ClassFactory<B> gives null?
    Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?

    I had a nightmare last night. I was dreaming that I’m 64-bit and my blanket is 32-bit and I couldn’t cover myself with it, so I’ve spent the whole night freezing. And in the morning I find that my blanket just had fallen off the bed. =S (from: bash.org.ru)

    //always looking for job opportunities in AU/NZ/US/CA/Europe :P
    willCodeForFood(Arrays.asList("Java","PHP","C++","bash","Assembler","XML","XHTML","CSS","JS","PL/SQL"));

    USE [code] TAGS! Read this FAQ if you are new here. If this post was helpful, please rate it!

  7. #7
    Join Date
    Jul 2005
    Location
    Currently in Mexico City
    Posts
    568

    Re: Question about inheritance in Java

    Sorry, was stupid, corrected my mistake already =)
    Last edited by Xeel; October 11th, 2009 at 01:35 AM.
    Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?

    I had a nightmare last night. I was dreaming that I’m 64-bit and my blanket is 32-bit and I couldn’t cover myself with it, so I’ve spent the whole night freezing. And in the morning I find that my blanket just had fallen off the bed. =S (from: bash.org.ru)

    //always looking for job opportunities in AU/NZ/US/CA/Europe :P
    willCodeForFood(Arrays.asList("Java","PHP","C++","bash","Assembler","XML","XHTML","CSS","JS","PL/SQL"));

    USE [code] TAGS! Read this FAQ if you are new here. If this post was helpful, please rate it!

  8. #8
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Question about inheritance in Java

    I don't know why you're using these techniques, but even with a modern JVM, reflection is relatively inefficient, and it's less clear to read and maintain.

    Why not use OO techniques instead?

    The hardest part of the software task is arriving at a complete and consistent specification, and much of the essence of building a program is in fact the debugging of the specification...
    F. Brooks
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured