Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
抽象类中的Java泛型子实例_Java_Generics_Abstract Class - Fatal编程技术网

抽象类中的Java泛型子实例

抽象类中的Java泛型子实例,java,generics,abstract-class,Java,Generics,Abstract Class,我有一个抽象类,一些child和一个抽象类的泛型DAO public abstract class Person { ... } public class User extends Person { ... } public class Client extends Person { ... } public PersonDao <T extends Person> { ... } 如何实例化泛型子类并返回子对象?在Java中无法执行此操作,因为。你可以想方设法解决你的问题。基本上

我有一个抽象类,一些child和一个抽象类的泛型DAO

public abstract class Person { ... }
public class User extends Person { ... }
public class Client extends Person { ... }
public PersonDao <T extends Person> { ... }

如何实例化泛型子类并返回子对象?

在Java中无法执行此操作,因为。你可以想方设法解决你的问题。基本上,您必须提供您想要获得的类。

在Java中,您不能这样做,因为。你可以想方设法解决你的问题。基本上,您必须提供您想要获得的类。

new T()
由于Java中的原因是不允许的。无论如何,泛型的全部目的是确保编译时代码中的类型安全,而数据访问类并不能确保,因为数据库中的条目可能对应于
用户
客户端
。换句话说,SQL语句和子类之间没有映射(请注意,这通常由诸如Hibernate之类的ORM框架处理)。解决方案是在代码中提供精确指定结果类型的附加参数。通常,
Person
的每个子类都应该有自己的DAO实现(即
UserDao
ClientDao
),而
PersonDao
方法应该是抽象的,例如:

public abstract class PersonDao<T extends Person> { 

     abstract T select(int id);

     ...
}

public class UserDao extends PersonDao<User> {

    public User select(int id) throws SQLException {
        // Assuming there is a type column to differentiate between types of Person
        String sql = "SELECT * FROM person WHERE per_id=? and type=?";
        PreparedStatement ps = con.preparedStatement(sql);
        ps.setInt(1, id);
        ps.setString(2, User.class.getName());
        ResultSet rs = ps.executeQuery();
        User user = null;

        if(rs.next()) {
            user = new User();

            user.setId(rs.getInt("per_id"));
            user.setName(rs.getString("per_name"));
        }

        return user;
    }

    ...
}
旁注:您的代码片段没有显示如何关闭JDBC资源。请确保在实际代码中这样做。

newt()
不允许使用,因为在Java中。无论如何,泛型的全部目的是确保编译时代码中的类型安全,而数据访问类并不能确保,因为数据库中的条目可能对应于
用户
客户端
。换句话说,SQL语句和子类之间没有映射(请注意,这通常由诸如Hibernate之类的ORM框架处理)。解决方案是在代码中提供精确指定结果类型的附加参数。通常,
Person
的每个子类都应该有自己的DAO实现(即
UserDao
ClientDao
),而
PersonDao
方法应该是抽象的,例如:

public abstract class PersonDao<T extends Person> { 

     abstract T select(int id);

     ...
}

public class UserDao extends PersonDao<User> {

    public User select(int id) throws SQLException {
        // Assuming there is a type column to differentiate between types of Person
        String sql = "SELECT * FROM person WHERE per_id=? and type=?";
        PreparedStatement ps = con.preparedStatement(sql);
        ps.setInt(1, id);
        ps.setString(2, User.class.getName());
        ResultSet rs = ps.executeQuery();
        User user = null;

        if(rs.next()) {
            user = new User();

            user.setId(rs.getInt("per_id"));
            user.setName(rs.getString("per_name"));
        }

        return user;
    }

    ...
}
旁注:您的代码片段没有显示如何关闭JDBC资源。确保在真正的代码中这样做

public class PersonDao<T extends Person> { 

     private Class<T> type;

     public PersonDao(Class<T> type) {
         this.type = type;
     }

     public T select(int id) {
        String sql = "SELECT * FROM person WHERE per_id=? and type=?";
        PreparedStatement ps = con.preparedStatement(sql);
        ps.setInt(1, id);
        ps.setString(2, type.getName());
        ResultSet rs = ps.executeQuery();
        T t = null;

        if(rs.next()) {
            t = type.newInstance();

            t.setId(rs.getInt("per_id"));
            t.setName(rs.getString("per_name"));
        }

        return t;
     }

     ...
}