Tengo la siguiente interfaz:

public interface Result<T extends Serializable> extends Serializable{
    T getResult();
}

Con esa interfaz, no puedo definir una variable de tipo

Result<List<Integer>>

porque la Lista no es serializable.

Sin embargo, si puedo cambiar la interfaz:

public interface Result<T> extends Serializable{
    T getResult();
}

Ahora se convierte en imposible de implementar, con la comprobación en tiempo de compilación, porque no hay ninguna garantía de que T es serializable, y el punto entero de la clase para almacenar el resultado, así que puedo volver más tarde, posiblemente después de una transferencia a través de internet.

Mi pregunta es esta, ¿hay una manera de declarar una variable, por lo que es de dos tipos, o hay alguna otra manera de hacer esto que no estoy viendo? Así que, tal vez algo como:

(List<Integer> extends Serializable) value = new ArrayList();

Estoy tratando de poner la mayor parte de la carga de este problema en la aplicación, por lo que los consumidores en el futuro de esta interfaz son conscientes del problema.

Gracias por su ayuda!

Aquí es un ejemplo más detallado de lo que estoy tratando de hacer:
Estoy llamando a un servidor, El resultado de lo que quiero almacenar en un objeto de resultado, pero yo no quiero tener que lidiar con el bastidor. Así, cada método que se puede llamar en el servidor se define el tipo del resultado por el uso de medicamentos genéricos. Este objeto de resultado también de la tienda otros meta-datos sobre el resultado, por ejemplo, tal vez había demasiada información para volver. En muchos casos se desea utilizar una lista, pero la interfaz de Lista no es serializable, aunque muchas de las implementaciones.

Así que, ¿cómo puedo especificar que el tipo de las utilizadas deben ser Serializables, pero todavía permiten la Lista(y no una implementación específica de la Lista) para que se utiliza?

Puede usted aclarar lo que usted está tratando de hacer? Tal vez dar un ejemplo más extenso?
Usted debe saber que incluso si T es marcado como serializable, todavía puede contener una referencia a un objeto que no es serialiazble. Por tanto, es pasar los genéricos de análisis estático pero no en tiempo de ejecución.
Cierto, pero eso es un error que los consumidores, y no a un defecto en mi código. Si un consumidor declara algo como serializable, y luego no cumplir con los requisitos de ser serializable, no hay nada que yo pueda hacer.

OriginalEl autor Megamug | 2009-01-20

7 Comentarios

  1. 9

    Que necesitamos declarar una variable de tipo Result<? extends List<Integer>>.

    La comprobación de tipo sabe que List no serializable, pero un subtipo de List puede ser serializable.

    Aquí está el código de ejemplo. La implementación de la interfaz se acaba de hacer con las clases internas anónimas. Se puede ver que el getResult devolverá un List<Integer> en la 2ª objeto

       Result<Integer> res = new Result<Integer>() {
    
            Integer myInteger;
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public Integer getResult() {
                return myInteger;
            }
    
            @Override
            public void addResult(Integer input) {
                this.myInteger = input;
            }
        };
    
        Integer check = res.getResult();
    
    
        Result<? extends List<Integer>> res2 = new Result<ArrayList<Integer>>() {
    
            ArrayList<Integer> myList;
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public ArrayList<Integer> getResult() {
                return myList;
            }
    
            @Override 
            public void addResult(ArrayList<Integer> input) {
                this.myList = input;
            }
    
        };
    
        List<Integer> check2 = res2.getResult();

    Edit: el ejemplo más completa mediante la implementación de un void addResult(T input) método de interfaz

    Impresionante! Yo estaba empezando a pensar que no hay una manera de hacerlo. Gracias!

    OriginalEl autor Patrick

  2. 3

    Aunque la Lista de la interfaz de no implementar Serializable, todos los de la Colección integrada de las implementaciones de hacer. Esto se discute en las Colecciones Implementaciones tutorial.

    Las Colecciones de Diseño de preguntas frecuentes tiene una pregunta «¿Por qué no ampliar la Colección de Cloneable y Serializable?» que habla acerca de por qué el Sol diseñado sin ampliar Serializable.

    A la derecha, yo a entender el razonamiento detrás de todo esto, pero en este caso necesitaba para asegurarse de que la Lista que estaba siendo utilizado fue serializable.

    OriginalEl autor Powerlord

  3. 2

    Usted puede simplemente declarar la variable como Result<ArrayList<Integer>>. Mientras el programa para la List interfaz, realmente no has sacrificado replaceability.

    Yo iba a sugerir también la creación de una nueva interfaz de ListResult:

    public interface ListResult<T extends Serializable & List<E extends Serializable>>
            implements Result<T> {
        T getResult();
    }

    pero, a continuación, usted todavía tiene que declarar la variable como ListResult<ArrayList<Integer>>. Así que me gustaría ir a la ruta más simple.

    No quiero forzar al servidor para especificar la aplicación que será devuelto porque entonces no va a ser capaz de ser pasivamente cambiado.

    OriginalEl autor Michael Myers

  4. 0

    Si su intención es utilizar el tipo de Resultado para las listas en general, y lo que quiere es asegurarse de que los elementos de la lista son serializables, se podría definir así:

    public interface Result<T extends List<? extends Serializable>> {}

    De esa manera, se podría definir algo como:

    Result<List<Integer>> r;

    Pero algo como esto no compila:

    Result<List<List>> r;

    Ahora bien, si usted desea utilizar el resultado de ambas, por ejemplo, un Entero, y para la Lista, entonces el tipo no es necesario ser serializable, ¿verdad? En ese caso yo realmente no entiendo cuál es el objetivo.

    Se necesita tener en cuenta para cualquier objeto que es serializable, no sólo de la Lista. Debe ser serializable por lo que puede ser transferido entre el servidor y el cliente.
    Si el tipo debe ser serializable, entonces no puede ser Lista. Si desea utilizar de la Lista, no se puede exigir que sea serializable. No creo que ver qué tipo de solución que está buscando, lo siento.
    Puede ser una Lista y ser Serializable. Por ejemplo, java.util.ArrayList.
    No entiendo cómo esas dos cosas son opuestas. Quiero dejar a mi los consumidores el uso de la Lista de la aplicación de su elección, siempre que es Serializable.
    En realidad, hay tres maneras de consumir. Obtener el resultado, establecer el resultado y transferir el resultado. Para la transferencia, usted debe saber que es Serializable. Para llegar, debes saber que es una Lista. Para establecer, usted debe saber que es una Lista y Serializable. Quiero tener cada uno conoce sólo lo que necesitan. Espero que ayude!

    OriginalEl autor Fabian Steeg

  5. 0

    Que se puede, creo:

    public class Thing<T extends Serializable> implements Serializable {
        private static class Holder<V extends Serializable> {
            private final V value;
            private Holder(V value) {
                this.value = value;
            }
        }
        private Holder<? extends List<T>> holder;
        private <V extends List<T> & Serializable> void set(V value) {
            holder = new Holder<V>(value);
        }
    }

    Hace que se ven feos suficiente para usted?

    Puedo sugerir que usted no intente hacer cumplir la aplicación de Serializable usando el Java de tipo estático del sistema? Es sólo una interfaz porque las anotaciones no estaban sobre los de entonces. No es práctico para su aplicación. OTOH, usted puede aplicar usando un comprobador de tipos que hace un análisis estático en un sistema cerrado.

    Esto no es exactamente lo que necesito porque no puedo asumir que es una lista. Sin embargo, cuando acabo de hacer la «V se extiende T & Serializable», me sale una excepción. Este podría ser un tema de otra pregunta, sin embargo.

    OriginalEl autor Tom Hawtin – tackline

  6. 0

    La forma en que terminé la solución de este problema es el uso de esta como de la interfaz:

    public interface Result<T> extends Serializable{
        T getResult();
    }

    A continuación, crear una aplicación para cada uno de los diferentes tipos de colecciones, así como para cualquier objeto.

    Así, por ejemplo, aquí está lo que el ListResult clase quedaría así:

    public class ListResult<T> implements Result<List<T>>{
        public List<T> getResult(){
            //return result
        }
    
        public <V extends List<T> & Serializable> void setResult(V result){
            //store result
        }
    }

    OriginalEl autor Megamug

  7. -1

    Pensamiento inicial. Si usted está planeando sobre el uso de la serialización para cualquier tipo de largo plazo de almacenamiento de datos, no. La serialización no está garantizado para trabajar entre las invocaciones de la JVM.

    Probablemente no se debe ampliar Serializable a menos que usted está agregando la funcionalidad relacionada con la serialización de Objetos. En cambio, la clase que implementa el Resultado también debe implementar Serializable.

    Yo no soy de usarlo por largo plazo de almacenamiento de datos. Lo siento, cuando me dijo: «todo el propósito de la clase es almacenar el resultado», me refería más tarde en la misma instancia del programa.

    OriginalEl autor Matthew Brubaker

Dejar respuesta

Please enter your comment!
Please enter your name here