Proposed API for JEP 259: Stack-Walking API

Mandy Chung mandy.chung at oracle.com
Sun Nov 1 04:36:21 UTC 2015


In fact, <T> T walk(Function<Stream<StackFrame>, T> function, …) - without ? extends T change,

You can do:
    Function<Stream<StackWalker.StackFrame>, String> funct;
    CharSequence chars =  sw.walk(funct, i -> i);

I think it’s right to declare the return type of the function is "? extends T”. 

Mandy


> On Oct 31, 2015, at 5:01 PM, Timo Kinnunen <timo.kinnunen at gmail.com> wrote:
> 
> Hi, 
>  
> Regarding “
> I was pondering it and that’s why not changed in the last update.  I agree with the upper bounded wildcard "? extends T” for the return type of the function.  
>>  
> How does changing the type from “T” to “? extends T” aid the method caller in any way? If the caller has a Function like this:
>  
>                 Function<Stream<StackWalker.StackFrame>, String> funct;
>  
> but they wished they could have walk use T=CharSequence instead, then they can simply assign the value returned from walk to a CharSequence variable:
>  
>                 String result = sw.walk(funct, i -> i);
>                 CharSequence chars = result;
>  
>  
> Isn’t “? extends T” pointless here?
>  
>  
>  
>  
>  
> Sent from Mail for Windows 10
>  
>  
> 
> From: Mandy Chung
> Sent: Saturday, October 31, 2015 23:59
> To: Remi Forax
> Cc: core-libs-dev at openjdk.java.net
> Subject: Re: Proposed API for JEP 259: Stack-Walking API
>  
>  
>  
> > On Oct 31, 2015, at 11:29 AM, Remi Forax <forax at univ-mlv.fr> wrote:
> > 
> > Hi Mandy,
> > I've crawled the code and the documentation again.
> > 
> > In the doc and in the code, a lambda with one parameter doesn't require parenthesis around the parameter,
> >  (s) -> s.doSomething()
> > should be
> >  s -> s.doSomething().
> > 
>  
> Oh right.  (It didn’t look right to me but didn’t pay attention to it).
>  
> > 
> > In the doc of StackWalker,
> > in the first example, the local variable 'frame' should be named ‘callerClass'
> > 
>  
> Fixed
> > 
> > In the doc of getCallerClass(),
> > the first example do a skip(2) which i believe is not necessary anymore,
>  
> It has to skip two frames.  Use the second example, the stack looks like this:
>  
> StackWalk::getCallerClass
> Util::getResourceBundle
> Foo::init
> :
> :
>  
> > also instead of Optional.orElse, orElseGet is better because it avoids to evaluate
> > Thread.currentThread().getClass() if not necessary.
> > 
> > So the example should be:
> >   walk(s -> s.map(StackFrame::getDeclaringClass)
> >              .findFirst()).orElseGet(() -> Thread.currentThread().getClass());
> > 
>  
> This would return Util.class instead of Foo.class
>  
> > In the second example, the field walker should be declared 'final’.
>  
> Sure. Fixed.
>  
> > 
> > And as i said earlier, the signature of walk() is:
> >  <T> T walk(Function<? super Stream<StackWalker.StackFrame>, ? extends T> function, IntUnaryOperator batchSizeMapper)
> > 
>  
> I was pondering it and that’s why not changed in the last update.  I agree with the upper bounded wildcard "? extends T” for the return type of the function.  
>  
> But for the function’s input argument, can you help me understand why it should take "? super Stream<StackWalker.StackFrame>”?  Is it useful to have function accepting supertype of Stream<StackFrame> rather than Stream<StackFrame>?  VM should be the only source producing this StackFrame stream.
>  
> On the other hand, I wonder if the stream argument should be Stream<? extends StackFrame> that may allow future implementation change.
>  
> <T> T walk(Function<Stream<? extends StackWalker.StackFrame>, ? extends T> function, …)
>  
> Mandy




More information about the core-libs-dev mailing list