문제
안에. 그물, 나는 다음과 같은 일을 할 수 있습니다.
public static T[] CreateAndFillArray<T>(int size) where T : new()
{
T[] array = new T[size];
for (int i = size - 1; i >= 0; i--)
array[i] = new T();
return array;
}
"여기서 t : new ()"절을 지정해야합니다.
Java에서 어떻게 하는가?
해결책
Java에서는 일반적인 배열을 인스턴스화 할 수 없습니다. (예 : 새로운 t [크기]가 작동 할 수 없음) 런타임에 제네릭 유형이 손실되고 ( "삭제") 복구 할 수 없기 때문입니다.
예를 들어 New Arraylist와 같이 사용할 수없는 이유가 있습니까?u003CT> ()?
다른 팁
t를 매개 변수로 전달하지 않는 한 Java에서 일반 "t"유형의 배열을 만들 수 없습니다.
public static <T> T[] createAndFillArray(Class<T> cls, int size) {
T[] result = (T[]) Array.newInstance(cls, size);
for (int i=0; i<size; i++) {
result[i] = cls.newInstance();
}
return result;
}
Java에는 동등한 구성이 없습니다. 생성자가 포함 된 클래스에는 컴파일 시간 안전이 없습니다.
런타임에 수행 할 수 있지만 Null T 또는 클래스를 매개 변수로 전달해야합니다. 사용 된 실제 유형 매개 변수는 런타임에 유지되지 않습니다.
public static <T> T[] createAndFillArray(T sampleObject, int size) throws Exception {
Class<T> klass = sampleObject.getClass();
T[] arr = (T[]) Array.newInstance(klass, size);
for (int i = 0; i < size; i++) {
arr[i] = klass.newInstance();
}
return arr;
}
위의 내용은 작동하지만 공개 인수 생성자가 없으면 예외를 던집니다. 컴파일러가 하나 있음을 시행 할 수는 없습니다.
편집 : chssply76이 나를 이길 수 있으므로 위의 코드를 수정하여 실제 객체 샘플을 전달하는 예제를 제시하여 수행 방법을 보여줍니다. 일반적으로 이러한 경우 샘플 오브젝트가 배열에서 끝나지 않기 때문에 클래스에 전달됩니다.
이 아이디어를 사용하여 다른 답변에서 컴파일 타임의 부족을 고칠 수 있습니다.
import java.lang.reflect.Array;
public class Main
{
public static void main(String[] args)
{
final String[] array;
array = createAndFillArray(String.class, 10, new StringCreator());
for(final String s : array)
{
System.out.println(s);
}
}
public static <T> T[] createAndFillArray(final Class<T> clazz,
final int size,
final Creator<T> creator)
{
T[] result = (T[]) Array.newInstance(clazz, size);
for (int i=0; i<size; i++)
{
result[i] = creator.newInstance();
}
return result;
}
}
interface Creator<T>
{
T newInstance();
}
class StringCreator
implements Creator<String>
{
public String newInstance()
{
// not the best example since String is immutable but you get the idea
// you could even have newInstance take an int which is the index of the
// item being created if that could be useful (which it might).
return ("hello");
}
}
이것은 단순히 무리를 호출하지 않고 원하는 경우 생성자를 제어 할 수 있기 때문에 실제로 설명하는 C# 방식보다 유연합니다.
Java는 구조 유형 검사를 지원하지 않기 때문에 Java에서는이 작업을 수행 할 수 없습니다.
Scala는하지만 적절한 인터페이스를 구현하는 것보다 훨씬 느립니다 (내부적으로 반사를 사용하여 함수 호출을하기 때문에). Scala는 물체 생성자 형태로 제약 조건을 설정할 수 없습니다. JVM은 유형 삭제를 사용하므로 일반 코드는 실제로 작동하는 유형을 알지 못하므로 어쨌든 해당 유형의 새로운 객체를 구성 할 수 없습니다.