由于Java泛型的实现,您不能拥有这样的代码:
public class GenSet<E> {
private E a[];
public GenSet() {
a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
}
}
Run Code Online (Sandbox Code Playgroud)
如何在保持类型安全的同时实现这一点?
我在Java论坛上看到了这样的解决方案:
import java.lang.reflect.Array;
class Stack<T> {
public Stack(Class<T> clazz, int capacity) {
array = (T[])Array.newInstance(clazz, capacity);
}
private final T[] array;
}
Run Code Online (Sandbox Code Playgroud)
但我真的不知道发生了什么.
假设你有一个arraylist定义如下:
ArrayList<String> someData = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
稍后在您的代码中,由于泛型,您可以这样说:
String someLine = someData.get(0);
Run Code Online (Sandbox Code Playgroud)
并且编译器完全知道它将获得一个字符串.是的仿制药!但是,这将失败:
String[] arrayOfData = someData.toArray();
Run Code Online (Sandbox Code Playgroud)
toArray()将始终返回一个对象数组,而不是已定义的泛型数组.为什么该get(x)方法知道它返回什么,但toArray()默认为Objects?
我正在使用Java 6.
我无法让我的内部类使用与其封闭类相同的泛型类.目前我有
public class TernarySearchTree < T > {
...
protected class TSTNode < T > {
// index values for accessing relatives array
protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
protected char splitchar;
protected TSTNode < T > [] relatives;
private T data;
protected TSTNode(char splitchar, TSTNode < T > parent) {
this.splitchar = splitchar;
relatives = new TSTNode[4];
relatives[PARENT] = parent;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我收到了警告
类型参数T隐藏类型T.
如果我从内部类中删除类型参数(即<T> …
可能重复:
我无法在Java中创建通用数组类型的原因是什么?
HashSet<Integer>[] rows = new HashSet<Integer>[9];
Run Code Online (Sandbox Code Playgroud)
给我一个编译错误:通用数组创建.
我想初始化一个成对数组,但我的方式并不完全正确。这是我第一次写它的方式:
Pair<String, Integer>[] pair = new Pair[5];
Run Code Online (Sandbox Code Playgroud)
它被接受并且可以工作,但仍然存在以下警告:
“未经检查的分配:
'android.util.Pair[]'到'android.util.Pair<Java.lang.String, Java.lang.Integer>[]'...
我已经尝试过这样做:
Pair<String, Integer>[] pair = new Pair<String, Integer>[5];
Run Code Online (Sandbox Code Playgroud)
但它不起作用。
您无法创建参数化类型的数组,因此Eclipse中的此代码
ArrayList<Integer>[] list = new ArrayList[1];
Run Code Online (Sandbox Code Playgroud)
无法参数化,但Eclipse显示警告
类型安全:类型的表达式
ArrayList[]需要未经检查的转换才能符合ArrayList<Integer>[]
并且还显示建议推断通用类型参数,它在提交时不执行任何操作.
推断通用类型参数在识别出可以进行此替换的所有位置之后,通过参数化类型替换泛型类型的原始类型.
这个建议应该删除还是我遗失了什么?
我想通过attributeNames这是collection of string一种方法setColumnNames,它接受string array.
public Map<String, String> getAttributes(String rowKey, Collection<String> attributeNames, String columnFamily) {
try {
SliceQuery<String, String, String> query = HFactory.createSliceQuery(keyspace, StringSerializer.get(), StringSerializer.get(), StringSerializer.get()).
setKey(rowKey).setColumnFamily(columnFamily).setColumnNames(attributeNames);
} catch (HectorException e) {
LOG.error("Exception in CassandraHectorClient::getAttributes " +e+ ", RowKey = " +rowKey+ ", Attribute Names = " +attributeNames);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
定义 setColumnNames
SliceQuery<K, N, V> setColumnNames(N... columnNames);
Run Code Online (Sandbox Code Playgroud)
我每次都得到这个例外 -
The method setColumnNames(String...) in the type SliceQuery<String,String,String> is not applicable for the …Run Code Online (Sandbox Code Playgroud) 我正在编写一些java代码,我想在我的主类Array中编写方法。该类实现了 ImplementableClass。前者扩展了 Iterable。Array 类有一个类型。
实现类.java:
public interface ImplementableClass<E> extends Iterable<E>{
public void insertObject(E obj);
public E removeObj(E obj);
}
Run Code Online (Sandbox Code Playgroud)
主要.java:
public class Array<Integer> implements ImplementableClass<E>{
public void insertObject(E obj){
}
public E removeLastObject(E obj){
}
//... main method and others below...
}
Run Code Online (Sandbox Code Playgroud)
我对上面两个文件中的代码有一些疑问。
阅读java文档,Iterable是E类型(泛型值)。据我了解,接口只是“实现”它们的类中必须使用的方法的“蓝图”。从基本的角度来看,这里不应该有任何变数。话虽如此,您可能会看到,我确实也在 Main 的 ImplementableClass 中声明了这些方法。话虽这么说,我有几个问题:
当在我的 Array 类中声明 ImplementableClass 类的方法时,这会“覆盖”我的 ImplementableClass 类中的方法,对吗?
由于“E obj”是两种方法中的参数,因此每当我在 Array 类中声明我的方法时,它们是否必须相同?我应该将什么传递给方法?“E obj”是什么意思?
我想创建一个可以保存 E 类型对象的数组。这意味着每当我实例化一个新对象时,Array<Integer> theArray = new Array<Integer>我都可以在 Array 实例上调用 Array 类上的方法,对吗?(即 theArray.removeLastObject() )我应该传递什么作为参数?
为什么Iterable<E>在这种情况下有用?
我的理解new ArrayList<String>()是将其转换为原始类型,并且使用大量的语法糖来假装Object的这个ArrayList就像String的ArrayList.Java将此称为类型擦除.
这是我用Java写的:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("foo");
String s = stringList.get(0);
}
Run Code Online (Sandbox Code Playgroud)
当我反编译字节码时,我得到了这个:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList();
stringList.add("foo");
String s = (String)stringList.get(0);
}
Run Code Online (Sandbox Code Playgroud)
为什么无法使用编译器为类型擦除提取的"shtick" 自动new T[]转换为(T[]) new Object[] 自动转换?
请不要将我引用到这个问题:我无法在Java中创建通用数组类型的原因是什么?特别是这个评论:
问题比答案更深刻,因此需要进一步调查.如你所说的类型信息被删除,在编译代码中我们没有两个泛型类型之间的区别 - 我们只有基类型 - 所以为什么
T[]- 编译到Object[].在这种情况下,一切都会很好 - 数组将记住它是使用对象类型创建的,并将保存所有类型.然而,对我来说,真正的问题是数组是协变的意味着Animal[]可以分配给Object[].另一方面,泛型不是ArrayList<Animal>不能分配的ArrayList<Object>
因为这个逻辑是有缺陷的!
这里有两个进程.
编译器强制执行"人为" …
一些开发人员通过创建Object[]并强制转换为通用类型来创建通用类型的数组,如以下示例代码所示:
public class ArrTest<E> {
public void test(E a){
E[] b = (E[])new Object[1];
b[0] = a;
System.out.println(b[0]);
}
public static void main(String[] args){
ArrTest<String> t = new ArrTest<String>();
t.test("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
该示例将起作用,并且仅显示警告:Type safety: Unchecked cast from Object[] to E[]。
灰心吗?这是创建泛型类型的数组的最佳方法吗?如果我在软件中广泛使用此对象,是否会导致意外的结果或异常?
我正在为我的 Java 期中学习而学习,但我在 reified 类型方面遇到了一些问题。这里有一堂课是错误的,但我不明白为什么。有人可以帮助我,也许能给我一些解释吗?当然,错误与具体化类型有关。
class Conversion {
public static <T> T[] toArray(Collection<T> c) {
T[] a = new T[c.size()];
int i = 0;
for (T x: c) a[i++] = x;
return a;
}
}
Run Code Online (Sandbox Code Playgroud) java ×12
generics ×9
arrays ×7
collections ×1
eclipse ×1
interface ×1
java-6 ×1
reflection ×1
string ×1