相关疑难解决方法(0)

List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的?

我对Java泛型如何处理继承/多态性感到困惑.

假设以下层次结构 -

动物(父母)

- (儿童)

所以假设我有一个方法doSomething(List<Animal> animals).根据所有继承和多态的规则,我会假设a List<Dog> a List<Animal>而a List<Cat> a List<Animal>- 所以任何一个都可以传递给这个方法.不是这样.如果我想实现这种行为,我必须明确告诉该方法接受一个Animal的任何子类的列表doSomething(List<? extends Animal> animals).

我知道这是Java的行为.我的问题是为什么?为什么多态通常是隐含的,但是当涉及泛型时必须指定它?

java generics polymorphism inheritance

727
推荐指数
10
解决办法
10万
查看次数

Java泛型类型擦除:何时以及发生了什么?

在Oracle的网站上读到了Java的类型擦除.

什么时候发生类型擦除?在编译时还是运行时?当班级加载?当类被实例化时?

很多站点(包括上面提到的官方教程)都说在编译时会发生类型擦除.如果在编译时完全删除了类型信息,那么当调用使用泛型的方法而没有类型信息或错误的类型信息时,JDK如何检查类型兼容性?

考虑以下示例:Say class A有一个方法,empty(Box<? extends Number> b).我们编译A.java并获取类文件A.class.

public class A {
    public static void empty(Box<? extends Number> b) {}
}
Run Code Online (Sandbox Code Playgroud)
public class Box<T> {}
Run Code Online (Sandbox Code Playgroud)

现在我们创建另一个类B,该类empty使用非参数化参数(原始类型)调用该方法:empty(new Box()).如果我们编译B.javaA.class在类路径中,javac的是足够聪明,引发警告.所以A.class 一些类型信息存储在其中.

public class B {
    public static void invoke() {
        // java: unchecked method invocation:
        //  method empty in class A is applied to given types
        //  required: Box<? extends java.lang.Number>
        //  found: …
Run Code Online (Sandbox Code Playgroud)

java generics type-erasure

233
推荐指数
6
解决办法
8万
查看次数

是否可以创建一个使用EasyMock实现多个接口的模拟对象?

是否可以创建一个使用EasyMock实现多个接口的模拟对象?

例如,界面Foo和界面Closeable

在Rhino Mocks中,您可以在创建模拟对象时提供多个接口,但EasyMock的createMock()方法只需要一种类型.

难道possbile与EasyMock的实现这一点,而不诉诸创建扩展双方暂时接口的后退FooCloseable,然后嘲讽吗?

java unit-testing rhino-mocks easymock mocking

42
推荐指数
4
解决办法
2万
查看次数

Java:instanceof Generic

有没有办法找到泛型的类型?

if (T instanceof String) {
    // do something...
}
Run Code Online (Sandbox Code Playgroud)

以上绝对不会编译.

java generics instanceof

33
推荐指数
2
解决办法
4万
查看次数

可能的Java泛型(模板)专业化(覆盖具有特定类型的模板类型)

我想知道在Java中专门化泛型类型的选项是什么,即在模板化的类中对某些类型进行特定的覆盖.

在我的例子中,我是一个泛型类(类型为T)通常返回null,但返回""(空字符串),当T是String类型时,或者当它是Integer类型时返回0(零)等.

仅提供方法的类型特定重载会产生"方法不明确"错误:

例如:

public class Hacking {

  public static void main(String[] args) {
    Bar<Integer> barInt = new Bar<Integer>();
    Bar<String> barString = new Bar<String>();

    // OK, returns null
    System.out.println(barInt.get(new Integer(4)));

    // ERROR: The method get(String) is ambiguous for the type Bar<String>
    System.out.println(barString.get(new String("foo")));
  }

  public static class Bar<T> {

    public T get(T x) {
      return null;
    }

    public String get(String x) {
      return "";
    }  
  }
}
Run Code Online (Sandbox Code Playgroud)

是使用特定类型子类化泛型类的唯一选项(请参阅以下示例中的StringBar?

  public static void main(String[] args) {
    Bar<Integer> barInt = new Bar<Integer>();
    StringBar …
Run Code Online (Sandbox Code Playgroud)

java generics

25
推荐指数
2
解决办法
2万
查看次数

在Kotlin中以任何方式从相同的通用接口继承两次(使用不同的类型)?

我在我的代码中有一个场景,我想要一个类来实现两个不同类型的接口,比如这个例子:

interface Speaker<T> {
    fun talk(value: T)
}

class Multilinguist : Speaker<String>, Speaker<Float> {
    override fun talk(value: String) {
        println("greetings")
    }

    override fun talk(value: Float) {
        // Do something fun like transmit it along a serial port
    }
}
Run Code Online (Sandbox Code Playgroud)

Kotlin对此不满意,引用:

Type parameter T of 'Speaker' has inconsistent values: kotlin.String, kotlin.Float
A supertype appears twice
Run Code Online (Sandbox Code Playgroud)

我知道一个可能的解决方案是实现以下代码,我在其中实现接口,<Any>然后自己检查类型并将它们委托给它们的函数.

interface Speaker<T> {
    fun talk(value: T)
}

class Multilinguist : Speaker<Any> {
    override fun talk(value: Any) {
        when (value) {
            is String -> …
Run Code Online (Sandbox Code Playgroud)

generics interface multiple-inheritance kotlin

21
推荐指数
1
解决办法
2086
查看次数

重载泛型方法时Java 5和6之间的行为不同

我已经运行到Java的泛型的问题:在相同的代码编译和Java 6中正常工作,但将无法编译,因为在Java 5中同一消失的我有一个重载的方法的文件TestErasure.java ,称为"方法":

import java.util.ArrayList;
import java.util.List;

public class TestErasure {
 public static Object method(List<Object> list) {
     System.out.println("method(List<Object> list)");
     return null;
 }

 public static String method(List<String> list) {
     System.out.println("method(List<String> list)");
     return null;
 }

 public static void main(String[] args) {
     method(new ArrayList<Object>()); 
     method(new ArrayList<String>()); 
 }
}
Run Code Online (Sandbox Code Playgroud)

在Java 5中,我得到了预期的编译错误,指出"方法"的擦除是相同的:

$ javac -version
javac 1.5.0_19
$ javac TestErasure.java
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
        public static String method(List<String> list) {
                             ^
TestErasure.java:17: method(java.util.List<java.lang.Object>) in TestErasure cannot be applied …
Run Code Online (Sandbox Code Playgroud)

java generics jvm

18
推荐指数
1
解决办法
4809
查看次数

Java和Kotlin使用泛型进行投射.丢失类型安全

在使用Kotlin/Java进行编码时,我在使用强制转换和泛型时偶然发现了一些奇怪的东西.似乎有可能让类型系统认为列表是类型List<Foo>,而它实际上是一个List<Object>.

任何人都可以向我解释为什么这是可能的?

以下是Kotlin和Java中的一个例子:

Kotlin中的例子

fun <T> test(obj: Any): List<T> {
    val ts = ArrayList<T>()
    ts.add(obj as T)
    return ts
}

fun <T> test2(obj: Any): T {
    return obj as T
}

fun <T> test3(obj: Any): List<T> {
    val ts = ArrayList<T>()
    ts.add(test2(obj))
    return ts
}


fun main(args: Array<String>) {
    val x = test<Double>(1) // Returns a list of Integers and doesn't error
    println(x)

    val y = test2<Double>(1) // Casts the Int object to a Double.
    println(y) …
Run Code Online (Sandbox Code Playgroud)

java generics casting kotlin erasure

9
推荐指数
2
解决办法
612
查看次数

检查包含Java中对象的引用的类名

class A {
}

class B extends A {
}

class TestType {
   public static void main(String args[]) {
      A a = new B();
      // I wish to use reference 'a' to check the Reference-Type which is 'A'.
   }
}
Run Code Online (Sandbox Code Playgroud)

有可能吗?如果没有,那么请说明原因.

java

6
推荐指数
1
解决办法
1009
查看次数

集合成为原始类型

例如,我们有一些AbsractClass

package inherit;

import java.util.HashSet;
import java.util.Set;

/**
 * TODO: Add comment
 *
 * @author Ruslan Ibragimov
 */
public abstract class AbstractClass<T extends Integer> {

    private Set<String> strings = new HashSet<>();

    private T value;

    public Set<String> getStrings() {
        return strings;
    }

    public void setStrings(Set<String> strings) {
        this.strings = strings;
    }

    public void addString(String string) {
        strings.add(string);
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一些孩子:

package inherit;

/**
 * TODO: …
Run Code Online (Sandbox Code Playgroud)

java generics inheritance

6
推荐指数
1
解决办法
120
查看次数