Java中使用不兼容类型的错误是什么?

时间:2017-03-13 14:20:09

标签: java generics

下面的这个错误,我只需要一个可以读取一些资源的方向,一个搜索标签,它封装了必要的先决条件,以便学习可以防止这样的错误的解决方案。

confest.py

错误的对应行。

public partial class Cad_Prod : Form
{
   private static readonly SQLiteConnection conn1 =
         new SQLiteConnection(("data source=X.s3db");
   private static DataTable produtos;
   private static DataTable produtos;
   private static DataTable AutoDataTable => 
      produtos?? (produtos = GetAutos());           
   private static DataTable CategoryDataTable => 
      categoria ?? (categoria = GetCategories());            

   int prodstart = 0;
   public Cad_Prod() { InitializeComponent(); }

   public void Cad_Prod_Load(object sender, EventArgs e)  {  }
   private static DataTable GetAutos()
   {
      string query = "SELECT * FROM Cad_Prod";
      try
      {
          using (SQLiteCommand comm = new SQLiteCommand(query, conn1))
          using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(comm))
          {
            conn1.Open();
            DataTable produtos = new DataTable();
            adapter.Fill(produtos); 
            return produtos;
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show(this, ex.Message, "Erro", 
          MessageBoxButtons.OK, MessageBoxIcon.Error);
          throw;
      }
   }
   private static DataTable GetCategories()
   {
      string query2 = "SELECT * FROM Cat";
      try
      {
         using (SQLiteCommand comm2 = new SQLiteCommand(query2, conn1))
         using (SQLiteDataAdapter adapter2 = new SQLiteDataAdapter(comm2))
            {
            conn1.Open();
            DataTable categoria = new DataTable();
            adapter2.Fill(categoria);
            return categoria;
            }
      }
      catch (Exception ex)
      {
          MessageBox.Show(this, ex.Message, "Erro", 
          MessageBoxButtons.OK, MessageBoxIcon.Error);
          throw;
      }
  }

  private void PopulateView()
  {
     int auxCat = int.Parse(produtos.Rows[prodstart]
            .ItemArray[4].ToString()) - 1;

     txtProdutoNome.Text = produtos.Rows[prodstart]
            .ItemArray[1].ToString();
     txtProdutoPreco.Text = produtos.Rows[prodstart]
            .ItemArray[2].ToString();
     txtProdutoQtd.Text = produtos.Rows[prodstart]
            .ItemArray[3].ToString();
     cbbCategoria.Text = categoria.Rows[auxCat]
            .ItemArray[1].ToString();
  }

  private void btnAvancar_Click(object sender, EventArgs e)
  {
    prodstart = prodstart + 1;
    PopulateView();
  }

  private void btnVoltar_Click(object sender, EventArgs e)
  {
    prodstart = prodstart - 1;
    PopulateView();
  }
}

1 个答案:

答案 0 :(得分:2)

这主要是Foo<Subclass>不是Foo<Superclass>的子类型的示例。请参阅:Is List<Dog> a subclass of List<Animal>?

问题在于FizzBuzzNetwork.class

的签名
  

C.class的类型,其中C是类,接口或数组类型(第4.3节)的名称,是Class。

所以FizzBuzzNetwork.classClass<FizzBuzzNetwork>,它不是Class<FizzBuzzNetwork<PRM,?>>的超类,就像List<Animal>不是List<Dog>的超类一样。

你可以通过将操作数转换为原始Class引用来解决这个问题,然后向下转发它:

(Class<? extends FizzBuzzNetwork<PRM, ?>>) (Class) FizzBuzzNetwork.class

这会为您提供未经检查的投射警告,您可以通过SuppressWarnings("unchecked")来抑制警告。但请记住,警告是有原因的。具体来说,由于erasure,类的参数在运行时不存在。因此Class<? extends FizzBuzzNetwork<PRM, ?>> 与<{1}}完全相同,这可能会导致令人困惑的错误。

例如,如果您使用其Class<FizzBuzzNetwork>方法进行检查,则无法检查某些内容是否是instanceof的实例,而不是FizzBuzzNetwork<PRM, ?> - 该信息从运行时删除。检查将成功(它们都是FizzBu​​zzNetwork对象,这是所有检查可以查找的对象),但尝试使用它来处理PRM可能会导致ClassCastException。

如果您想要安全,那么您应该只需要FizzBuzzNetwork<NotAPrm, ?>,就像Java提供的那样。然后,每当你使用它(例如检查,转换等)时,你只能在编译时获得它的FizzBu​​zzNetwork-ness。这是一件好事,因为所有的运行时也能够给你。您必须找到一些其他机制来确定您使用的对象是否为Class<FizzBuzzNetwork>