我有一个方法可以比较对象的值(如字符串、日期、数字...)并根据结果返回 true 或 false。
我已经为此方法创建了一个单元测试,但在测试 clob 比较时遇到问题,因为使用 JUnit 我没有连接,并且如果我使用 SerialClob 创建两个 clob(具有相同的内容) ,我得到具有相同引用的对象(因此比较 clob 的部分没有测试),我不明白为什么两个“new”生成相同的对象引用?
还有一件事我不明白,如果我将字符串与 clob (相同的值)进行比较,则会使用比较 clob 的代码,而 instanceof 不应该是相同的......!
我期望的是:当我比较 2 个不同的 clob 时,作为对象比较为 false,因为字符串(toString 输出)为 false,它检测到对象是 instanceof clob,因此将它们转换为字符串,然后比较字符串值。
这是我的代码(例如简化的):
import java.io.*;
import java.sql.*;
import javax.sql.rowset.serial.*;
public class TestClob {
public static void main(String[] args) throws SerialException, SQLException {
boolean result;
Object text1="abcdef", text2="abcdef";
Clob clob1 = new SerialClob(((String) text1).toCharArray());
Clob clob2 = new SerialClob(((String) text2).toCharArray());
Clob clob3 = new SerialClob("abcdefg".toCharArray());
System.out.println("TEST 1, basic string comparison");
System.out.println("-------------------------------");
result = haveSameValue(text1, text2);
System.out.println("result: "+result);
System.out.println("\nTEST 2, clob vs string");
System.out.println("----------------------");
result = haveSameValue(clob1, text1);
System.out.println("result: "+result);
System.out.println("\nTEST 3, different clobs objects but same value");
System.out.println("----------------------------------------------");
result = haveSameValue(clob1, clob2);
System.out.println("result: "+result);
System.out.println("\nTEST 4, different clobs");
System.out.println("-----------------------");
result = haveSameValue(clob1, clob3);
System.out.println("result: "+result);
}
public static boolean haveSameValue(Object obj1, Object obj2) {
String sObj1, sObj2, sObj1Class, sObj2Class;
boolean result = false;
if (obj1!=null && obj2!=null) {
sObj1Class = obj1.getClass().toString().toLowerCase();
sObj2Class = obj2.getClass().toString().toLowerCase();
System.out.println(" Objects class : sObj1Class="+sObj1Class+", sObj2Class="+sObj2Class);
System.out.println(" OBJECT : obj1="+obj1+", obj2="+obj2+", => equal as object? "+obj1.equals(obj2));
if (!obj1.equals(obj2)) {
sObj1=obj1.toString();
sObj2=obj2.toString();
System.out.println(" STRING : sObj1="+sObj1+", sObj2="+sObj2+", => equal as string? "+sObj1.equals(sObj2));
if (!sObj1.equals(sObj2)) {
if (obj1 instanceof java.sql.Clob || obj2 instanceof java.sql.Clob) {
sObj1 = ClobToString(obj1);
sObj2 = ClobToString(obj2);
System.out.println(" CLOB : sObj1="+sObj1+", sObj2="+sObj2+" => equal as clob? "+sObj1.equals(sObj2));
result = sObj1.equals(sObj2);
}
// other comparisons (as a date, timestamp, number...)
}
}
}
return result;
}
public static String ClobToString(Object object) {
if (object==null) {
return null;
}
else if (object instanceof java.sql.Clob) {
StringBuilder sb = new StringBuilder();
try {
Reader reader = ((java.sql.Clob) object).getCharacterStream();
BufferedReader br = new BufferedReader(reader);
String line;
while(null != (line = br.readLine())) {
sb.append(line);
}
br.close();
return sb.toString();
}
catch (Exception e) {
System.out.println("error : "+e.getMessage());
return object.toString();
}
}
else {
return object.toString();
}
}
}
这是输出:
TEST 1, basic string comparison
-------------------------------
Objects class : sObj1Class=class java.lang.string, sObj2Class=class java.lang.string
OBJECT : obj1=abcdef, obj2=abcdef, => equal as object? true
result: true
TEST 2, clob vs string
----------------------
Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class java.lang.string
OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=abcdef, => equal as object? false
STRING : sObj1=javax.sql.rowset.serial.SerialClob@df59efc3, sObj2=abcdef, => equal as string? false
CLOB : sObj1=abcdef, sObj2=abcdef => equal as clob? true
result: true
TEST 3, different clobs objects but same value
----------------------------------------------
Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class javax.sql.rowset.serial.serialclob
OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=javax.sql.rowset.serial.SerialClob@df59efc3, => equal as object? true
result: true
TEST 4, different clobs
-----------------------
Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class javax.sql.rowset.serial.serialclob
OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=javax.sql.rowset.serial.SerialClob@bd7d1c2, => equal as object? false
STRING : sObj1=javax.sql.rowset.serial.SerialClob@df59efc3, sObj2=javax.sql.rowset.serial.SerialClob@bd7d1c2, => equal as string? false
CLOB : sObj1=abcdef, sObj2=abcdefg => equal as clob? false
result: false
变量
clob1
和 clob2
引用不同的对象,因为新对象是使用 new
关键字创建的。然而,这些对象具有相同的“价值”。 SerialClob.equals()
方法的定义方式是,当两个 SerialClob
实例具有相同的值时,它们彼此相等:
将此 SerialClob 与指定对象进行比较。当且仅当参数不是
并且是表示与此对象相同的字符序列的true
对象时,结果为null
。SerialClob
这里就是这种情况,它们具有相同的值
"abcdef"
。这意味着 if
块
if (!obj1.equals(obj2)) {
...
}
未输入。因此,不会执行进一步的检查,因为您已经知道它们“相等”。