Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #29669 > unrolled thread

Accessibility of suBclass-fields from suPERclass (reflection)

Started byAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
First post2014-08-15 00:58 +0000
Last post2014-08-16 11:00 -0400
Articles 20 on this page of 25 — 8 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-15 00:58 +0000
    Re: Accessibility of suBclass-fields from suPERclass (reflection) Lew <lewbloch@gmail.com> - 2014-08-15 15:20 -0700
      Re: Accessibility of suBclass-fields from suPERclass (reflection) Steven Simpson <ss@domain.invalid> - 2014-08-16 00:11 +0100
        Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-16 00:10 +0000
    Re: Accessibility of suBclass-fields from suPERclass (reflection) Arne Vajhøj <arne@vajhoej.dk> - 2014-08-15 23:26 -0400
      Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-16 08:46 +0000
        Re: Accessibility of suBclass-fields from suPERclass (reflection) Robert Klemme <shortcutter@googlemail.com> - 2014-08-16 12:27 +0200
          Re: Accessibility of suBclass-fields from suPERclass (reflection) "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2014-08-16 13:37 +0100
            Re: Accessibility of suBclass-fields from suPERclass (reflection) Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-08-16 09:47 -0400
            Re: Accessibility of suBclass-fields from suPERclass (reflection) Robert Klemme <shortcutter@googlemail.com> - 2014-08-17 13:19 +0200
          Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-16 22:37 +0000
            Re: Accessibility of suBclass-fields from suPERclass (reflection) Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-08-16 20:22 -0400
              Re: Accessibility of suBclass-fields from suPERclass (reflection) Josip Almasi <joe@vrspace.org> - 2014-08-17 12:51 +0200
                Re: Accessibility of suBclass-fields from suPERclass (reflection) Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-08-17 07:54 -0400
                  Re: Accessibility of suBclass-fields from suPERclass (reflection) "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2014-08-17 13:44 +0100
                  Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-17 17:42 +0000
                    Re: Accessibility of suBclass-fields from suPERclass (reflection) Arne Vajhøj <arne@vajhoej.dk> - 2014-08-18 20:45 -0400
                      Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-20 18:47 +0000
                  Re: Accessibility of suBclass-fields from suPERclass (reflection) Josip Almasi <joe@vrspace.org> - 2014-08-18 17:19 +0200
              Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-17 18:04 +0000
                Re: Accessibility of suBclass-fields from suPERclass (reflection) Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-08-17 15:24 -0400
                  Re: Accessibility of suBclass-fields from suPERclass (reflection) Andreas Leitgeb <avl@auth.logic.tuwien.ac.at> - 2014-08-17 21:35 +0000
        Re: Accessibility of suBclass-fields from suPERclass (reflection) Josip Almasi <joe@vrspace.org> - 2014-08-16 12:31 +0200
        Re: Accessibility of suBclass-fields from suPERclass (reflection) Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-08-16 10:51 -0400
        Re: Accessibility of suBclass-fields from suPERclass (reflection) Arne Vajhøj <arne@vajhoej.dk> - 2014-08-16 11:00 -0400

Page 1 of 2  [1] 2  Next page →


#29669 — Accessibility of suBclass-fields from suPERclass (reflection)

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-15 00:58 +0000
SubjectAccessibility of suBclass-fields from suPERclass (reflection)
Message-ID<slrnluqmpu.fp3.avl@login.logic.tuwien.ac.at>
It is clear to me, that a class may need to protect its fields from direct
access by subclasses or unrelated classes, mostly because the developer of
a base class doesn't always know all derived or unrelated classes ahead of
time.

Otoh, someone who derives a class, or even does it in a statement block of
their own code, obviously can be expected to "know" and "trust" those
classes he derives or includes derivatives of.

E.g., someone writing this:
   public class Outer extends Base {
      static {
         class Inner extends Base { ... }
      }
   }
had better know/trust "class Base", and have no need to have his code
protected from reflective examination by class Base.

Now, apparently, the designers of Java felt differently, and to examine (by
use of reflection) the fields of "Inner" from within Base's code, Base has to
jump an extra hoop (namely calling setAccessibility(true)), requesting access
from an eventually installed SecurityManager.

Surprisingly (or not), that extra hoop is not required to examine "Outer"'s
fields from within "Base".  Also, it is not possible to mark an inner class
as public in an attempt to grant accessibility of "Inner" to "Base".

It makes no sense to me, why there is any defense-mechanism at all against 
field access from code within a known Baseclass.

[toc] | [next] | [standalone]


#29676

FromLew <lewbloch@gmail.com>
Date2014-08-15 15:20 -0700
Message-ID<8ebedaf9-6487-4897-8c97-a83356444138@googlegroups.com>
In reply to#29669
Andreas Leitgeb wrote:
> It is clear to me, that a class may need to protect its fields from direct
> access by subclasses or unrelated classes, mostly because the developer of
> a base class doesn't always know all derived or unrelated classes ahead of
> time.
> 
> Otoh, someone who derives a class, or even does it in a statement block of
> their own code, obviously can be expected to "know" and "trust" those
> classes he derives or includes derivatives of.
> 
> E.g., someone writing this:
>    public class Outer extends Base {
>       static {
>          class Inner extends Base { ... }
>       }
>    }
> 
> had better know/trust "class Base", and have no need to have his code
> protected from reflective examination by class Base.

Declaring that 'Inner' class inside the static initializer like that makes it deucedly hard to use.

> Now, apparently, the designers of Java felt differently, and to examine (by
> use of reflection) the fields of "Inner" from within Base's code, Base has to

It might have been easier if 'Inner' were an inner class of 'Outer'. I don't quite know how to parse out an inner class inside a static initializer block - it doesn't become an inner class of 'Outer', and it doesn't become a nested class of 'Outer' exactly. I think it can only be used inside that block. Honestly this one is a bit of a stumper for me.

Can you show me how to use such a declared class?

> jump an extra hoop (namely calling setAccessibility(true)), requesting access
> from an eventually installed SecurityManager.
> 
> Surprisingly (or not), that extra hoop is not required to examine "Outer"'s
> fields from within "Base".  Also, it is not possible to mark an inner class
> as public in an attempt to grant accessibility of "Inner" to "Base".
> 
> It makes no sense to me, why there is any defense-mechanism at all against 
> field access from code within a known Baseclass.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#29679

FromSteven Simpson <ss@domain.invalid>
Date2014-08-16 00:11 +0100
Message-ID<rmg2cb-p04.ln1@s.simpson148.btinternet.com>
In reply to#29676
On 15/08/14 23:20, Lew wrote:
> Andreas Leitgeb wrote:
>>     public class Outer extends Base {
>>        static {
>>           class Inner extends Base { ... }
>>        }
>>     }
>>

> I don't quite know how to parse out an inner class inside a static initializer block - it doesn't become an inner class of 'Outer', and it doesn't become a nested class of 'Outer' exactly. I think it can only be used inside that block. Honestly this one is a bit of a stumper for me.

It's surely the same as a local class in a static method, isn't it?


-- 
ss at comp dot lancs dot ac dot uk

[toc] | [prev] | [next] | [standalone]


#29681

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-16 00:10 +0000
Message-ID<slrnlut8bb.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29679
Steven Simpson <ss@domain.invalid> wrote:
> On 15/08/14 23:20, Lew wrote:
>> Andreas Leitgeb wrote:
>>>     public class Outer extends Base {
>>>        static {
>>>           class Inner extends Base { ... }
              ...
>>>        }
>>>     }
>> I don't quite know how to parse out an inner class inside a static initializer block - it doesn't become an inner class of 'Outer', and it doesn't become a nested class of 'Outer' exactly. I think it can only be used inside that block. Honestly this one is a bit of a stumper for me.
> It's surely the same as a local class in a static method, isn't it?

Exactly.  My fault, I forgot the ellipsis "..." following the inner class
inside the static-block to indicate further use of it within the same block. 

My point of course, had nothing to do with what code block exactly
it is in.  It was merely about accessing the class's guts from Base's
code.   Base's code has a this-pointer, and that's how it still accesses
that isolated class, provided that something in that static block actually
creates an instance of that inner class.

[toc] | [prev] | [next] | [standalone]


#29686

FromArne Vajhøj <arne@vajhoej.dk>
Date2014-08-15 23:26 -0400
Message-ID<53eecf6a$0$300$14726298@news.sunsite.dk>
In reply to#29669
On 8/14/2014 8:58 PM, Andreas Leitgeb wrote:
> It is clear to me, that a class may need to protect its fields from direct
> access by subclasses or unrelated classes, mostly because the developer of
> a base class doesn't always know all derived or unrelated classes ahead of
> time.
>
> Otoh, someone who derives a class, or even does it in a statement block of
> their own code, obviously can be expected to "know" and "trust" those
> classes he derives or includes derivatives of.
>
> E.g., someone writing this:
>     public class Outer extends Base {
>        static {
>           class Inner extends Base { ... }
>        }
>     }
> had better know/trust "class Base", and have no need to have his code
> protected from reflective examination by class Base.
>
> Now, apparently, the designers of Java felt differently, and to examine (by
> use of reflection) the fields of "Inner" from within Base's code, Base has to
> jump an extra hoop (namely calling setAccessibility(true)), requesting access
> from an eventually installed SecurityManager.
>
> Surprisingly (or not), that extra hoop is not required to examine "Outer"'s
> fields from within "Base".  Also, it is not possible to mark an inner class
> as public in an attempt to grant accessibility of "Inner" to "Base".
>
> It makes no sense to me, why there is any defense-mechanism at all against
> field access from code within a known Baseclass.

Can you produce an example showing the problem?

My first attempt:

package august;

import java.lang.reflect.Field;

public class AccessFun {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.test();
	}
}

class Base {
	private static void test(Base o) {
		System.out.print(o.getClass().getName() + " : ");
		try {
			Field f = o.getClass().getField("v");
			int v = f.getInt(o);
			System.out.println(v);
		} catch (NoSuchFieldException | SecurityException | 
IllegalArgumentException | IllegalAccessException e) {
			System.out.println("no access");
		}
	}
	private static void testWith(Base o) {
		System.out.print(o.getClass().getName() + " (with) : ");
		try {
			Field f = o.getClass().getDeclaredField("v");
			f.setAccessible(true);
			int v = f.getInt(o);
			System.out.println(v);
		} catch (NoSuchFieldException | SecurityException | 
IllegalArgumentException | IllegalAccessException e) {
			System.out.println("no access");
		}
	}
	public void test() {
		Outer o = (Outer)this;
		test(o);
		test(o.one);
		test(o.two);
		testWith(o);
		testWith(o.one);
		testWith(o.two);
	}
}

class Outer extends Base {
	private static Base hack;
	public Base one;
	public Base two;
	private int v = 0;
     static class InnerOne extends Base {
  	   private int v = 1;
     }
     static {
        class InnerTwo extends Base {
     	   private int v = 2;
        }
        hack = new InnerTwo();
     }
     public Outer() {
         one = new InnerOne();
         two = hack;
     }
}

gave:

august.Outer : no access
august.Outer$InnerOne : no access
august.Outer$1InnerTwo : no access
august.Outer (with) : 0
august.Outer$InnerOne (with) : 1
august.Outer$1InnerTwo (with) : 2

which looks consistent to me.

Arne

[toc] | [prev] | [next] | [standalone]


#29687

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-16 08:46 +0000
Message-ID<slrnluu6ir.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29686
Arne Vajhøj <arne@vajhoej.dk> wrote:
> Can you produce an example showing the problem?

My 'problem' is understanding, why setAccessible(true) is even necessary

> My first attempt:
> [...]
> 	private static void test(Base o) {
> 		System.out.print(o.getClass().getName() + " : ");
> 		try {
> 			Field f = o.getClass().getField("v");
> 			int v = f.getInt(o);
> 			System.out.println(v);
> 		} catch (NoSuchFieldException | SecurityException | 
> [throws...]
> 	private static void testWith(Base o) {
> 		System.out.print(o.getClass().getName() + " (with) : ");
> 		try {
> 			Field f = o.getClass().getDeclaredField("v");
> 			f.setAccessible(true);
> 			int v = f.getInt(o);
> 			System.out.println(v);
> 		} catch (NoSuchFieldException | SecurityException | 
> [throws not]
> which looks consistent to me.

Consistent maybe, but why cannot Base access these fields by default?

I'm not complaining about that extra setAccessibility(true), I just 
would like to see an example of where a Base-class accessing its children
could be a security issue.  I'm not talking of some arbitrary class
attempting access, but about the target class's parent (or grandparent)
class.

I'm probably unaware of some risk, and learning about it was my reason
for the posting.

[toc] | [prev] | [next] | [standalone]


#29692

FromRobert Klemme <shortcutter@googlemail.com>
Date2014-08-16 12:27 +0200
Message-ID<c58q1fF9v1tU1@mid.individual.net>
In reply to#29687
On 16.08.2014 10:46, Andreas Leitgeb wrote:

> Consistent maybe, but why cannot Base access these fields by default?
>
> I'm not complaining about that extra setAccessibility(true), I just
> would like to see an example of where a Base-class accessing its children
> could be a security issue.  I'm not talking of some arbitrary class
> attempting access, but about the target class's parent (or grandparent)
> class.
>
> I'm probably unaware of some risk, and learning about it was my reason
> for the posting.

If I understand your issue correctly: this is not about security but 
about design principles.  Dependency always goes up the inheritance 
chain - not downwards.  Meaning, all subclasses have knowledge about 
their superclasses but not vice versa.

If you want a superclass to access subclass state you need to provide 
means for it, e.g. defining abstract accessor or other methods in the 
base class which then must be implemented in subclasses.

There are languages out there that handle this differently.  For 
example, in Ruby instance variables are immediately accessible for all 
instance methods - regardless of their defining class.  But then again, 
Ruby has a quite different approach to visibility and accessibility.

Kind regards

	robert

[toc] | [prev] | [next] | [standalone]


#29694

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2014-08-16 13:37 +0100
Message-ID<PM2dne2nDIwqzHLOnZ2dnUVZ8g-dnZ2d@bt.com>
In reply to#29692
Robert Klemme wrote:

> If I understand your issue correctly: this is not about security but
> about design principles.  Dependency always goes up the inheritance
> chain - not downwards.  Meaning, all subclasses have knowledge about
> their superclasses but not vice versa.

Agreed, though I think "always" is a little strong.  It is possible to have 
clusters of co-designed classes where the superclass "knows about" it's 
subclasses.  For instance the superclass could act as a factory for instances 
of its sublclasses, where the subclasses (what they are and how many of them 
there are, etc) is hidden from the consumer code.

(In such cases I'd often like to be able to declare the superclass as "final 
except that it can have subclasses in the same package")

    -- chris 

[toc] | [prev] | [next] | [standalone]


#29697

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-08-16 09:47 -0400
Message-ID<lsnnd8$te3$1@dont-email.me>
In reply to#29694
On 8/16/2014 8:37 AM, Chris Uppal wrote:
> Robert Klemme wrote:
>
>> If I understand your issue correctly: this is not about security but
>> about design principles.  Dependency always goes up the inheritance
>> chain - not downwards.  Meaning, all subclasses have knowledge about
>> their superclasses but not vice versa.
>
> Agreed, though I think "always" is a little strong.  It is possible to have
> clusters of co-designed classes where the superclass "knows about" it's
> subclasses.  For instance the superclass could act as a factory for instances
> of its sublclasses, where the subclasses (what they are and how many of them
> there are, etc) is hidden from the consumer code.
>
> (In such cases I'd often like to be able to declare the superclass as "final
> except that it can have subclasses in the same package")

     Make the superclass constructor package-private, and you'll get a
fairly good approximation to "package-final."

     But back up a bit: What's the nature of the "knows about" relation
between superclass and subclass?  In ordinary Java, "knows about" is
handled by requiring the "known-about" class to implement an interface,
and there's no need for the superclass (or any other client) to know
how the interface is implemented.  Why snoop around with reflection?

     Okay, maybe the "knows about" is in support of Version 2.0 of the
Parsifal Plugin Protocol, and isn't really related to the external
purpose of the subclass: You don't want to expose the PPP2 methods to
clients, because they'd abuse them and/or get into trouble when you
upgrade to PPP3.  In that sort of case one can implement the interface
in an inner class of the subclass, and provide that inner class to
the superclass for its private use.  (I'd have to think a bit about
how to do so cleanly; it's tempting to hand the accessor inner class
instance to the superclass' constructor, but that's probably a
premature `this' leakage.  Maybe the superclass could expose a
`protected void setAccessor(InnerClassInterface accessor)' method?)

-- 
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#29705

FromRobert Klemme <shortcutter@googlemail.com>
Date2014-08-17 13:19 +0200
Message-ID<c5bhepFra3sU1@mid.individual.net>
In reply to#29694
On 16.08.2014 14:37, Chris Uppal wrote:
> Robert Klemme wrote:
>
>> If I understand your issue correctly: this is not about security but
>> about design principles.  Dependency always goes up the inheritance
>> chain - not downwards.  Meaning, all subclasses have knowledge about
>> their superclasses but not vice versa.
>
> Agreed, though I think "always" is a little strong.  It is possible to have
> clusters of co-designed classes where the superclass "knows about" it's
> subclasses.  For instance the superclass could act as a factory for instances
> of its sublclasses, where the subclasses (what they are and how many of them
> there are, etc) is hidden from the consumer code.

Still then the superclass needs to know zero about subclass internals. 
Of course, as long as the subclasses are visible to the superclass it 
can use them like any other class (e.g. a separate factory class) could. 
  But that's a rather weak dependency and has nothing to do with 
specifics of the interface or implementation of subclasses.

> (In such cases I'd often like to be able to declare the superclass as "final
> except that it can have subclasses in the same package")

I don't see the point.  Actually it's contradicting: a final class does 
not have subclasses - nowhere.  Eric provided a good means how to 
prevent subclassing in other places of the code where you do not want to 
allow it.

Cheers

	robert

[toc] | [prev] | [next] | [standalone]


#29700

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-16 22:37 +0000
Message-ID<slrnluvn8q.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29692
Robert Klemme <shortcutter@googlemail.com> wrote:
> On 16.08.2014 10:46, Andreas Leitgeb wrote:
>> I'm not complaining about that extra setAccessibility(true), I just
>> would like to see an example of where a Base-class accessing its children
>> could be a security issue.  I'm not talking of some arbitrary class
>> attempting access, but about the target class's parent (or grandparent)
>> class.

> If you want a superclass to access subclass state you need to provide 
> means for it, e.g. defining abstract accessor or other methods in the 
> base class which then must be implemented in subclasses.

I'll describe my situation a bit:

I have a special Base class, and each of its subclasses serve exactly
one purpose: a collection of name/value associations where the java-
compiler knows about the valid names, so as to detect accesses to
non-existing names already at compile-time.  (without that last premise,
I would have used HashMaps instead of subclasses)

Overall-operations, (e.g. resetting all values of a given subclass
instance) are done from Base-class by use of reflection.


On the topic itself, I meanwhile found a possible explanation
myself:  Maybe reflection doesn't really know or care at all
which code actually *does* a reflective access. So it can't
tell a getClass().getField(fieldName).get(this) situation from
foreignObj.getClass().getField(fieldName).get(foreignObj) in
the first place...

[toc] | [prev] | [next] | [standalone]


#29701

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-08-16 20:22 -0400
Message-ID<lsosjs$gtc$1@dont-email.me>
In reply to#29700
On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
> Robert Klemme <shortcutter@googlemail.com> wrote:
>> On 16.08.2014 10:46, Andreas Leitgeb wrote:
>>> I'm not complaining about that extra setAccessibility(true), I just
>>> would like to see an example of where a Base-class accessing its children
>>> could be a security issue.  I'm not talking of some arbitrary class
>>> attempting access, but about the target class's parent (or grandparent)
>>> class.
>
>> If you want a superclass to access subclass state you need to provide
>> means for it, e.g. defining abstract accessor or other methods in the
>> base class which then must be implemented in subclasses.
>
> I'll describe my situation a bit:
>
> I have a special Base class, and each of its subclasses serve exactly
> one purpose: a collection of name/value associations where the java-
> compiler knows about the valid names, so as to detect accesses to
> non-existing names already at compile-time.  (without that last premise,
> I would have used HashMaps instead of subclasses)

     Would an EnumMap serve?

> Overall-operations, (e.g. resetting all values of a given subclass
> instance) are done from Base-class by use of reflection.

     Why by reflection?  Why not by a reset() method, abstract in
the superclass?

     I'm confident you have reasons, but I'm sure I haven't yet
grasped them.


-- 
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#29703

FromJosip Almasi <joe@vrspace.org>
Date2014-08-17 12:51 +0200
Message-ID<lsq1fh$htv$1@gregory.bnet.hr>
In reply to#29701
On 08/17/2014 02:22 AM, Eric Sosman wrote:
> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>> Overall-operations, (e.g. resetting all values of a given subclass
>> instance) are done from Base-class by use of reflection.
>
>      Why by reflection?  Why not by a reset() method, abstract in
> the superclass?

Because it means coding in each subclass?

Regards...

[toc] | [prev] | [next] | [standalone]


#29706

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-08-17 07:54 -0400
Message-ID<lsq55r$1s1$1@dont-email.me>
In reply to#29703
On 8/17/2014 6:51 AM, Josip Almasi wrote:
> On 08/17/2014 02:22 AM, Eric Sosman wrote:
>> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>>> Overall-operations, (e.g. resetting all values of a given subclass
>>> instance) are done from Base-class by use of reflection.
>>
>>      Why by reflection?  Why not by a reset() method, abstract in
>> the superclass?
>
> Because it means coding in each subclass?

     Hmmm.  I suppose that would be a possible objection, but it
seems kind of far-fetched.  Nobody seems too terribly upset about
writing a separate equals() for every subclass that needs one;
why should a reset() method be more objectionable?

     Awful thought: A subclass that inherits equals() from its
superclass, where the superclass' equals() implementation uses
reflection to inspect the subclass' innards ...

-- 
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#29707

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2014-08-17 13:44 +0100
Message-ID<yqidnT-9-NVXMG3OnZ2dnUVZ8jGdnZ2d@bt.com>
In reply to#29706
Eric Sosman wrote:

>     Awful thought: A subclass that inherits equals() from its
> superclass, where the superclass' equals() implementation uses
> reflection to inspect the subclass' innards ...

<shiver/>

But.

Equals() implementations usually start by checking the class of the comparand, 
and that's reflection in my book.

<grin>Or just serialise both objects and do a byte-by-byte comparison on the 
results...</grin>

    -- chris 

[toc] | [prev] | [next] | [standalone]


#29708

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-17 17:42 +0000
Message-ID<slrnlv1qcj.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29706
Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
> On 8/17/2014 6:51 AM, Josip Almasi wrote:
>> On 08/17/2014 02:22 AM, Eric Sosman wrote:
>>> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>>>> Overall-operations, (e.g. resetting all values of a given subclass
>>>> instance) are done from Base-class by use of reflection.
>>>      Why by reflection?  Why not by a reset() method, abstract in
>>> the superclass?
>> Because it means coding in each subclass?

That really is the reason. And it's not just the reset(), but also 
another bunch of methods.

>      Awful thought: A subclass that inherits equals() from its
> superclass, where the superclass' equals() implementation uses
> reflection to inspect the subclass' innards ...

equals() is used from granddaddy class, aka Object ;-)

[toc] | [prev] | [next] | [standalone]


#29715

FromArne Vajhøj <arne@vajhoej.dk>
Date2014-08-18 20:45 -0400
Message-ID<53f29e2b$0$292$14726298@news.sunsite.dk>
In reply to#29708
On 8/17/2014 1:42 PM, Andreas Leitgeb wrote:
> Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
>> On 8/17/2014 6:51 AM, Josip Almasi wrote:
>>> On 08/17/2014 02:22 AM, Eric Sosman wrote:
>>>> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>>>>> Overall-operations, (e.g. resetting all values of a given subclass
>>>>> instance) are done from Base-class by use of reflection.
>>>>       Why by reflection?  Why not by a reset() method, abstract in
>>>> the superclass?
>>> Because it means coding in each subclass?
>
> That really is the reason. And it's not just the reset(), but also
> another bunch of methods.

I think there are two ideas you need to consider.

1) Make the fields in the sub classes protected instead of private.

This will allow you to avoid the setAccessible call.

(yes - protected allows not only access from below but also
access from above)

Saving a line of code is not important, but you will also get
rid of the restriction that your code will not run with a
security manager in place.

And I don't like to have such environmental restrictions
in code if it can be avoided.

2) Replace the reflection code in the base class with a
    cast to an interface and call of method - and use AspectJ
    to add interface and method implementation to all sub classes
    of the base class.

You still have the reflection code. But you have separated
the business logic code in the base class and reflection code
in a separate aspect.

So if a business logic code maintainer (or a code maintainer just
with his business logic hat on) need to look at the code, then the
base class just calls a method and that method is documented in
the JavaDoc for the interface - no need to dig down into the
reflection code.

The framework code maintainer (code maintainer with framework
hat on) can focus on the aspect.

Arne



[toc] | [prev] | [next] | [standalone]


#29773

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-20 18:47 +0000
Message-ID<slrnlv9rad.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29715
Arne Vajhøj <arne@vajhoej.dk> wrote:
> On 8/17/2014 1:42 PM, Andreas Leitgeb wrote:
>> Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
>>> On 8/17/2014 6:51 AM, Josip Almasi wrote:
>>>> On 08/17/2014 02:22 AM, Eric Sosman wrote:
>>>>> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>>>>>> Overall-operations, (e.g. resetting all values of a given subclass
>>>>>> instance) are done from Base-class by use of reflection.
>>>>> Why by reflection?  Why not by a reset() method, abstract in
>>>>> the superclass?
>>>> Because it means coding in each subclass?
>> That really is the reason. And it's not just the reset(), but also
>> another bunch of methods.
>
> I think there are two ideas you need to consider.
> 1) Make the fields in the sub classes protected instead of private.
> This will allow you to avoid the setAccessible call.

Actually, the fields themselves are already public.  Problem was,
that the subclasses appeared in contexts that weren't "accessible",
such as within a statement block (as an inner class).

The fields are really public final references to mutable objects,
so the usual caveats about exposing public fields do not apply.

> Saving a line of code is not important, but you will also get
> rid of the restriction that your code will not run with a
> security manager in place.

That's a non-issue in my case.  (But is of course good advice
in the general case)

> 2) Replace the reflection code in the base class with a
>     cast to an interface and call of method - and use AspectJ
>     to add interface and method implementation to all sub classes
>     of the base class.

That's something I'll have get into, some day...
Until I really understand that aspect-stuff, I'm kind of
suspicious of it ;)

The separation between business and framework already exists:
the base class is framework, whereas the subclasses with their
fields are business :)

I've got a plan B, too, that would avoid reflection, but that involves
overriding a method to return an array of all the referenced objects
in each subclass.  I happily avoid that as long as reflection and
setAccessibility work well enough for me.

[toc] | [prev] | [next] | [standalone]


#29714

FromJosip Almasi <joe@vrspace.org>
Date2014-08-18 17:19 +0200
Message-ID<lst5hn$sh9$1@gregory.bnet.hr>
In reply to#29706
On 08/17/2014 01:54 PM, Eric Sosman wrote:
> On 8/17/2014 6:51 AM, Josip Almasi wrote:
>> On 08/17/2014 02:22 AM, Eric Sosman wrote:
>>> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>>>> Overall-operations, (e.g. resetting all values of a given subclass
>>>> instance) are done from Base-class by use of reflection.
>>>
>>>      Why by reflection?  Why not by a reset() method, abstract in
>>> the superclass?
>>
>> Because it means coding in each subclass?
>
>      Hmmm.  I suppose that would be a possible objection, but it
> seems kind of far-fetched.  Nobody seems too terribly upset about
> writing a separate equals() for every subclass that needs one;
> why should a reset() method be more objectionable?

Because, equals() is called very often, and reset() is not.

>      Awful thought: A subclass that inherits equals() from its
> superclass, where the superclass' equals() implementation uses
> reflection to inspect the subclass' innards ...

;>

I know of two classes of problems that reflection solves mighty fine:
1) persistence
2) networking
I suppose anything else solved by marshalling is case for reflection.

Regards...

[toc] | [prev] | [next] | [standalone]


#29709

FromAndreas Leitgeb <avl@auth.logic.tuwien.ac.at>
Date2014-08-17 18:04 +0000
Message-ID<slrnlv1rkm.fp3.avl@login.logic.tuwien.ac.at>
In reply to#29701
Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
> On 8/16/2014 6:37 PM, Andreas Leitgeb wrote:
>> I have a special Base class, and each of its subclasses serve exactly
>> one purpose: a collection of name/value associations where the java-
>> compiler knows about the valid names, so as to detect accesses to
>> non-existing names already at compile-time.  (without that last premise,
>> I would have used HashMaps instead of subclasses)
>      Would an EnumMap serve?

In principle yes, but...

... element-access would look like:

     someSpecificEnumMapInstance.get( SomeSpecificEnum.itemName )

instead of:

     someSpecificSubClassInstance.itemName

;-)

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web