- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
How to implement a method of a Java interface with type parameter omitted by a Java sub-class
Sun, 2009-02-15, 06:46
Hi list,
I encountered an issue when I tried to implement a method of a Java
interface A by extends A's sub-class B, with B omitted A's type
parameters.
Let's give a detailed example here:
There is a Java interface A:
public interface A {
void run(T t);
}
Which has a type parameter and abstract method run(T t)
And a Java abstract class B with is sub-class of A. But, B, as it,
omitted type parameter of A. This is unsafe but valid in Java:
public abstract class B implements A {
public String me() {
return "I'm B";
}
}
Assume above class A and B have been compiled under javac, and packed
as jar library, and I can not patch it anymore. Now I need to write a
class S in Scala which extends B:
class S extends B {
override
def run[T <: String](t:T) = {println(t)}
}
scalac complained as:
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
class S needs to be abstract, since method run in trait A of type
(T)Unit is not defined
class S extends B {
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
method run overrides nothing
def run[T <: String](t:T) = {println(t)}
I than tried "forSome" type:
class S extends B {
override
def run(t:T forSome {type T <: String}) = {println(t)}
}
Again, I got:
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
class S needs to be abstract, since method run in trait A of type
(T)Unit is not defined
class S extends B {
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
method run overrides nothing
def run(t:T forSome {type T <: String}) = {println(t)}
It seems that, since B omitted A's type parameter T, I have no way to
get what is T, and can not successfully override/implement "run(T t)"
method.
I tried other forms of "forSome" usages, and always failed.
Any hints?
Thanks.
-Caoyuan
Fri, 2009-02-20, 05:47
#2
Re: Re: How to implement a method of a Java interface with typ
Hmm, is this a slightly different angle to the problem I asked about earlier today? - i.e. trying to implement a Java interface which has a reference to a raw un-parameterized type. I ended up doing the same thing - i.e. writing an "unsafe" Java translation method that sits between the interface and my scala code. It works, but left me with a bad taste in the mouth.
Ishaaq
2009/2/20 Caoyuan <dcaoyuan@gmail.com>
Ishaaq
2009/2/20 Caoyuan <dcaoyuan@gmail.com>
I've go a solution and blogged it at:
http://blogtrader.net/page/dcaoyuan/entry/scala_corner_case_1_implement
But I still hope scalac can resolve it directly, with a warning
message instead of failing to compile it.
-Caoyuan
On Sun, Feb 15, 2009 at 1:46 PM, Caoyuan <dcaoyuan@gmail.com> wrote:
> Hi list,
>
> I encountered an issue when I tried to implement a method of a Java
> interface A by extends A's sub-class B, with B omitted A's type
> parameters.
>
> Let's give a detailed example here:
>
> There is a Java interface A:
>
> public interface A<T extends String> {
> void run(T t);
> }
>
> Which has a type parameter <T extends String> and abstract method run(T t)
>
> And a Java abstract class B with is sub-class of A. But, B, as it,
> omitted type parameter of A. This is unsafe but valid in Java:
>
> public abstract class B implements A {
> public String me() {
> return "I'm B";
> }
> }
>
>
> Assume above class A and B have been compiled under javac, and packed
> as jar library, and I can not patch it anymore. Now I need to write a
> class S in Scala which extends B:
>
> class S extends B {
> override
> def run[T <: String](t:T) = {println(t)}
> }
>
> scalac complained as:
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
> class S needs to be abstract, since method run in trait A of type
> (T)Unit is not defined
> class S extends B {
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
> method run overrides nothing
> def run[T <: String](t:T) = {println(t)}
>
> I than tried "forSome" type:
>
> class S extends B {
> override
> def run(t:T forSome {type T <: String}) = {println(t)}
> }
>
> Again, I got:
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
> class S needs to be abstract, since method run in trait A of type
> (T)Unit is not defined
> class S extends B {
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
> method run overrides nothing
> def run(t:T forSome {type T <: String}) = {println(t)}
>
> It seems that, since B omitted A's type parameter T, I have no way to
> get what is T, and can not successfully override/implement "run(T t)"
> method.
>
> I tried other forms of "forSome" usages, and always failed.
>
> Any hints?
>
>
> Thanks.
>
> -Caoyuan
>
Fri, 2009-02-20, 06:07
#3
Re: Re: How to implement a method of a Java interface with typ
On Fri, Feb 20, 2009 at 12:40 PM, Ishaaq Chandy wrote:
> Hmm, is this a slightly different angle to the problem I asked about earlier
> today? - i.e. trying to implement a Java interface which has a reference to
> a raw un-parameterized type. I ended up doing the same thing - i.e. writing
> an "unsafe" Java translation method that sits between the interface and my
> scala code. It works, but left me with a bad taste in the mouth.
>
> Ishaaq
The signature of type parameter T is stored in the A's class file, I
think scalac could be smart enough to detect this case and compile it
with a warning message.
>
> 2009/2/20 Caoyuan
>>
>> I've go a solution and blogged it at:
>> http://blogtrader.net/page/dcaoyuan/entry/scala_corner_case_1_implement
>>
>> But I still hope scalac can resolve it directly, with a warning
>> message instead of failing to compile it.
>>
>> -Caoyuan
>>
>> On Sun, Feb 15, 2009 at 1:46 PM, Caoyuan wrote:
>> > Hi list,
>> >
>> > I encountered an issue when I tried to implement a method of a Java
>> > interface A by extends A's sub-class B, with B omitted A's type
>> > parameters.
>> >
>> > Let's give a detailed example here:
>> >
>> > There is a Java interface A:
>> >
>> > public interface A {
>> > void run(T t);
>> > }
>> >
>> > Which has a type parameter and abstract method run(T
>> > t)
>> >
>> > And a Java abstract class B with is sub-class of A. But, B, as it,
>> > omitted type parameter of A. This is unsafe but valid in Java:
>> >
>> > public abstract class B implements A {
>> > public String me() {
>> > return "I'm B";
>> > }
>> > }
>> >
>> >
>> > Assume above class A and B have been compiled under javac, and packed
>> > as jar library, and I can not patch it anymore. Now I need to write a
>> > class S in Scala which extends B:
>> >
>> > class S extends B {
>> > override
>> > def run[T <: String](t:T) = {println(t)}
>> > }
>> >
>> > scalac complained as:
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> > class S needs to be abstract, since method run in trait A of type
>> > (T)Unit is not defined
>> > class S extends B {
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> > method run overrides nothing
>> > def run[T <: String](t:T) = {println(t)}
>> >
>> > I than tried "forSome" type:
>> >
>> > class S extends B {
>> > override
>> > def run(t:T forSome {type T <: String}) = {println(t)}
>> > }
>> >
>> > Again, I got:
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> > class S needs to be abstract, since method run in trait A of type
>> > (T)Unit is not defined
>> > class S extends B {
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> > method run overrides nothing
>> > def run(t:T forSome {type T <: String}) = {println(t)}
>> >
>> > It seems that, since B omitted A's type parameter T, I have no way to
>> > get what is T, and can not successfully override/implement "run(T t)"
>> > method.
>> >
>> > I tried other forms of "forSome" usages, and always failed.
>> >
>> > Any hints?
>> >
>> >
>> > Thanks.
>> >
>> > -Caoyuan
>> >
>
>
Fri, 2009-02-20, 18:27
#4
Re: Re: How to implement a method of a Java interface with typ
File a bug report if it's not in Trac already.
On Thu, Feb 19, 2009 at 8:55 PM, Caoyuan <dcaoyuan@gmail.com> wrote:
On Thu, Feb 19, 2009 at 8:55 PM, Caoyuan <dcaoyuan@gmail.com> wrote:
On Fri, Feb 20, 2009 at 12:40 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
> Hmm, is this a slightly different angle to the problem I asked about earlier
> today? - i.e. trying to implement a Java interface which has a reference to
> a raw un-parameterized type. I ended up doing the same thing - i.e. writing
> an "unsafe" Java translation method that sits between the interface and my
> scala code. It works, but left me with a bad taste in the mouth.
>
> Ishaaq
The signature of type parameter T is stored in the A's class file, I
think scalac could be smart enough to detect this case and compile it
with a warning message.
>
> 2009/2/20 Caoyuan <dcaoyuan@gmail.com>
>>
>> I've go a solution and blogged it at:
>> http://blogtrader.net/page/dcaoyuan/entry/scala_corner_case_1_implement
>>
>> But I still hope scalac can resolve it directly, with a warning
>> message instead of failing to compile it.
>>
>> -Caoyuan
>>
>> On Sun, Feb 15, 2009 at 1:46 PM, Caoyuan <dcaoyuan@gmail.com> wrote:
>> > Hi list,
>> >
>> > I encountered an issue when I tried to implement a method of a Java
>> > interface A by extends A's sub-class B, with B omitted A's type
>> > parameters.
>> >
>> > Let's give a detailed example here:
>> >
>> > There is a Java interface A:
>> >
>> > public interface A<T extends String> {
>> > void run(T t);
>> > }
>> >
>> > Which has a type parameter <T extends String> and abstract method run(T
>> > t)
>> >
>> > And a Java abstract class B with is sub-class of A. But, B, as it,
>> > omitted type parameter of A. This is unsafe but valid in Java:
>> >
>> > public abstract class B implements A {
>> > public String me() {
>> > return "I'm B";
>> > }
>> > }
>> >
>> >
>> > Assume above class A and B have been compiled under javac, and packed
>> > as jar library, and I can not patch it anymore. Now I need to write a
>> > class S in Scala which extends B:
>> >
>> > class S extends B {
>> > override
>> > def run[T <: String](t:T) = {println(t)}
>> > }
>> >
>> > scalac complained as:
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> > class S needs to be abstract, since method run in trait A of type
>> > (T)Unit is not defined
>> > class S extends B {
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> > method run overrides nothing
>> > def run[T <: String](t:T) = {println(t)}
>> >
>> > I than tried "forSome" type:
>> >
>> > class S extends B {
>> > override
>> > def run(t:T forSome {type T <: String}) = {println(t)}
>> > }
>> >
>> > Again, I got:
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> > class S needs to be abstract, since method run in trait A of type
>> > (T)Unit is not defined
>> > class S extends B {
>> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> > method run overrides nothing
>> > def run(t:T forSome {type T <: String}) = {println(t)}
>> >
>> > It seems that, since B omitted A's type parameter T, I have no way to
>> > get what is T, and can not successfully override/implement "run(T t)"
>> > method.
>> >
>> > I tried other forms of "forSome" usages, and always failed.
>> >
>> > Any hints?
>> >
>> >
>> > Thanks.
>> >
>> > -Caoyuan
>> >
>
>
Fri, 2009-02-20, 23:07
#5
Re: Re: How to implement a method of a Java interface with typ
Done.
https://lampsvn.epfl.ch/trac/scala/ticket/1737
On Sat, Feb 21, 2009 at 1:21 AM, Jorge Ortiz wrote:
> File a bug report if it's not in Trac already.
>
> On Thu, Feb 19, 2009 at 8:55 PM, Caoyuan wrote:
>>
>> On Fri, Feb 20, 2009 at 12:40 PM, Ishaaq Chandy wrote:
>> > Hmm, is this a slightly different angle to the problem I asked about
>> > earlier
>> > today? - i.e. trying to implement a Java interface which has a reference
>> > to
>> > a raw un-parameterized type. I ended up doing the same thing - i.e.
>> > writing
>> > an "unsafe" Java translation method that sits between the interface and
>> > my
>> > scala code. It works, but left me with a bad taste in the mouth.
>> >
>> > Ishaaq
>>
>> The signature of type parameter T is stored in the A's class file, I
>> think scalac could be smart enough to detect this case and compile it
>> with a warning message.
>>
>> >
>> > 2009/2/20 Caoyuan
>> >>
>> >> I've go a solution and blogged it at:
>> >> http://blogtrader.net/page/dcaoyuan/entry/scala_corner_case_1_implement
>> >>
>> >> But I still hope scalac can resolve it directly, with a warning
>> >> message instead of failing to compile it.
>> >>
>> >> -Caoyuan
>> >>
>> >> On Sun, Feb 15, 2009 at 1:46 PM, Caoyuan wrote:
>> >> > Hi list,
>> >> >
>> >> > I encountered an issue when I tried to implement a method of a Java
>> >> > interface A by extends A's sub-class B, with B omitted A's type
>> >> > parameters.
>> >> >
>> >> > Let's give a detailed example here:
>> >> >
>> >> > There is a Java interface A:
>> >> >
>> >> > public interface A {
>> >> > void run(T t);
>> >> > }
>> >> >
>> >> > Which has a type parameter and abstract method
>> >> > run(T
>> >> > t)
>> >> >
>> >> > And a Java abstract class B with is sub-class of A. But, B, as it,
>> >> > omitted type parameter of A. This is unsafe but valid in Java:
>> >> >
>> >> > public abstract class B implements A {
>> >> > public String me() {
>> >> > return "I'm B";
>> >> > }
>> >> > }
>> >> >
>> >> >
>> >> > Assume above class A and B have been compiled under javac, and packed
>> >> > as jar library, and I can not patch it anymore. Now I need to write a
>> >> > class S in Scala which extends B:
>> >> >
>> >> > class S extends B {
>> >> > override
>> >> > def run[T <: String](t:T) = {println(t)}
>> >> > }
>> >> >
>> >> > scalac complained as:
>> >> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> >> > class S needs to be abstract, since method run in trait A of type
>> >> > (T)Unit is not defined
>> >> > class S extends B {
>> >> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> >> > method run overrides nothing
>> >> > def run[T <: String](t:T) = {println(t)}
>> >> >
>> >> > I than tried "forSome" type:
>> >> >
>> >> > class S extends B {
>> >> > override
>> >> > def run(t:T forSome {type T <: String}) = {println(t)}
>> >> > }
>> >> >
>> >> > Again, I got:
>> >> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
>> >> > class S needs to be abstract, since method run in trait A of type
>> >> > (T)Unit is not defined
>> >> > class S extends B {
>> >> > /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
>> >> > method run overrides nothing
>> >> > def run(t:T forSome {type T <: String}) = {println(t)}
>> >> >
>> >> > It seems that, since B omitted A's type parameter T, I have no way to
>> >> > get what is T, and can not successfully override/implement "run(T t)"
>> >> > method.
>> >> >
>> >> > I tried other forms of "forSome" usages, and always failed.
>> >> >
>> >> > Any hints?
>> >> >
>> >> >
>> >> > Thanks.
>> >> >
>> >> > -Caoyuan
>> >> >
>> >
>> >
>
>
I've go a solution and blogged it at:
http://blogtrader.net/page/dcaoyuan/entry/scala_corner_case_1_implement
But I still hope scalac can resolve it directly, with a warning
message instead of failing to compile it.
-Caoyuan
On Sun, Feb 15, 2009 at 1:46 PM, Caoyuan wrote:
> Hi list,
>
> I encountered an issue when I tried to implement a method of a Java
> interface A by extends A's sub-class B, with B omitted A's type
> parameters.
>
> Let's give a detailed example here:
>
> There is a Java interface A:
>
> public interface A {
> void run(T t);
> }
>
> Which has a type parameter and abstract method run(T t)
>
> And a Java abstract class B with is sub-class of A. But, B, as it,
> omitted type parameter of A. This is unsafe but valid in Java:
>
> public abstract class B implements A {
> public String me() {
> return "I'm B";
> }
> }
>
>
> Assume above class A and B have been compiled under javac, and packed
> as jar library, and I can not patch it anymore. Now I need to write a
> class S in Scala which extends B:
>
> class S extends B {
> override
> def run[T <: String](t:T) = {println(t)}
> }
>
> scalac complained as:
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
> class S needs to be abstract, since method run in trait A of type
> (T)Unit is not defined
> class S extends B {
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
> method run overrides nothing
> def run[T <: String](t:T) = {println(t)}
>
> I than tried "forSome" type:
>
> class S extends B {
> override
> def run(t:T forSome {type T <: String}) = {println(t)}
> }
>
> Again, I got:
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
> class S needs to be abstract, since method run in trait A of type
> (T)Unit is not defined
> class S extends B {
> /Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
> method run overrides nothing
> def run(t:T forSome {type T <: String}) = {println(t)}
>
> It seems that, since B omitted A's type parameter T, I have no way to
> get what is T, and can not successfully override/implement "run(T t)"
> method.
>
> I tried other forms of "forSome" usages, and always failed.
>
> Any hints?
>
>
> Thanks.
>
> -Caoyuan
>