Это:
var query = from something in someList where whereClause;
является сокращением для:
var query = someList.Where(something => whereClause);
Предполагая, что someList
является IEnumerable
, Where
относится к Enumerable.Where Extension Метод . Этот метод ожидает Func
, который вы можете определить следующим образом:
Func whereClause = address => address.Zip == 23456;
var query = someList.Where(whereClause);
serialVersionUID предоставляется для определения совместимости между десерализованным объектом и текущей версией класса. По сути, это не обязательно в первой версии класса или, в данном случае, в абстрактном базовом классе. У вас никогда не будет экземпляра этого абстрактного класса для сериализации / десериализации, поэтому ему не нужен serialVersionUID.
(Конечно, он генерирует предупреждение компилятора, от которого вы хотите избавиться, верно?)
Оказывается, комментарий Джеймса верен. SerialVersionUID абстрактного базового класса действительно распространяется на подклассы. В свете этого вам действительно нужен serialVersionUID в вашем базовом классе.
Код для тестирования:
import java.io.Serializable;
public abstract class Base implements Serializable {
private int x = 0;
private int y = 0;
private static final long serialVersionUID = 1L;
public String toString()
{
return "Base X: " + x + ", Base Y: " + y;
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Sub extends Base {
private int z = 0;
private static final long serialVersionUID = 1000L;
public String toString()
{
return super.toString() + ", Sub Z: " + z;
}
public static void main(String[] args)
{
Sub s1 = new Sub();
System.out.println( s1.toString() );
// Serialize the object and save it to a file
try {
FileOutputStream fout = new FileOutputStream("object.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject( s1 );
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
Sub s2 = null;
// Load the file and deserialize the object
try {
FileInputStream fin = new FileInputStream("object.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
s2 = (Sub) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println( s2.toString() );
}
}
Один раз запустите основную часть в Sub, чтобы заставить ее создать и сохранить объект. Затем измените serialVersionUID в базовом классе, закомментируйте строки в main, которые сохраняют объект (чтобы он не сохранял его снова, вы просто хотите загрузить старый), и снова запустите его. Это приведет к исключению
java.io.InvalidClassException: Base; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
Да, в общем, по той же причине, что и любому другому классу нужен серийный идентификатор - чтобы он не создавался для него. По сути, любой класс (не интерфейс), который реализует сериализуемый, должен определять идентификатор последовательной версии, иначе вы рискуете ошибками десериализации, когда один и тот же компилятор .class не находится в серверной и клиентской JVM.
Есть и другие варианты, если вы пытаетесь сделать что-то необычное. Я не уверен, что вы имеете в виду, говоря «это намерение подклассов ...». Собираетесь ли вы писать собственные методы сериализации (например, writeObject, readObject)? В таком случае есть и другие варианты работы с суперклассом.
см .: http://java.sun.com/javase/6/docs/api/java/io/Serializable.html
HTH Том