【问题标题】:What kind of Java type is "[B"?“[B”是什么Java类型?
【发布时间】:2011-06-04 03:50:14
【问题描述】:

我正在尝试通过 Java 代码 (Hibernate) 从 MySQL DB 获取 MD5 加密通行证。但是我既不能得到 String 也不能得到任何合理的 Java 类型。

我得到的唯一信息是这条无益的信息: java.lang.ClassCastException: [B 无法转换为 com.mysql.jdbc.Blob(或我尝试转换为的任何 Java 类型)。

这是我的方法:

public void testCrypto() {
        session.beginTransaction();
        // creates native SQL query
        // uses native MySQL's MD5 crypto
        final Blob pass = (Blob) session.createSQLQuery("SELECT MD5('somePass')")
            .list().get(0);
        session.getTransaction().commit();
}

这是完整的堆栈跟踪:

java.lang.ClassCastException: [B cannot be cast to com.mysql.jdbc.Blob
    at domain.DatabaseTest.testCrypto(DatabaseTest.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at junit.framework.TestCase.runTest(TestCase.java:168)
    at junit.framework.TestCase.runBare(TestCase.java:134)
    at junit.framework.TestResult$1.protect(TestResult.java:110)
    at junit.framework.TestResult.runProtected(TestResult.java:128)
    at junit.framework.TestResult.run(TestResult.java:113)
    at junit.framework.TestCase.run(TestCase.java:124)
    at junit.framework.TestSuite.runTest(TestSuite.java:232)
    at junit.framework.TestSuite.run(TestSuite.java:227)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

【问题讨论】:

    标签: java hibernate jdbc cryptography md5


    【解决方案1】:

    我的朋友是一个字节数组。在 JNI 中,[B 用于描述字节数组 ([) (B)。一个整数数组是 [I 等。

    您可以在此处获得有关字段描述符的更多信息:
    JNI Types and Data StructuresTable 3-2 应该是您要查找的内容)。

    【讨论】:

    • 谢谢您,您的帮助最大!
    • @rfeak 链接已过时。能发个新链接吗?
    • @Kasnady 我已经修复了链接:)
    【解决方案2】:

    这是byte[].class 的类名。试试这个:

    System.out.println(byte[].class.getName());
    

    输出(你猜对了):

    [B

    如果您想访问可读的名称,请使用Class.getCanonicalName()

    System.out.println(byte[].class.getCanonicalName());
    

    输出:

    字节[]

    【讨论】:

      【解决方案3】:

      正如其他答案所说,这是一个字节数组。

      如果要从字节数组中获取字符串,请使用 String 构造函数:

      public void testCrypto()
      {
              session.beginTransaction();
              // creates native SQL query
              // uses native MySQL's MD5 crypto
              final String pass = new String(session.createSQLQuery("SELECT MD5('somePass')")
                  .list().get(0));
              session.getTransaction().commit();
      }
      

      【讨论】:

      • 很好,但这真是奇怪的行为!此字符串与打印 mysql 控制台的内容完全相同。但是 pass.getBytes().length 说的是 32,MD5 应该是 128bits。我在哪里丢失了线索?
      • @Xorty:测量加密强度和字符串长度是有区别的。 MD5 会将任何输入转换为不超过 32 个十六进制字符的字符串。
      【解决方案4】:

      [B 是字节数组 (byte[]) 的编码类型名称,通常应该只出现在类型签名字符串中,因为它不是有效的类型名称。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 1970-01-01
        • 1970-01-01
        • 2010-11-30
        • 2015-05-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多