如果您想了解空串与NUll串和空串和null的知识,那么本篇文章将是您的不二之选。我们将深入剖析空串与NUll串的各个方面,并为您解答空串和null的疑在这篇文章中,我们将为您介绍空串与NUll串的相
如果您想了解空串与NUll串和空串和null的知识,那么本篇文章将是您的不二之选。我们将深入剖析空串与NUll串的各个方面,并为您解答空串和null的疑在这篇文章中,我们将为您介绍空串与NUll串的相关知识,同时也会详细的解释空串和null的运用方法,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- 空串与NUll串(空串和null)
- 3-java中String值为空字符串与null的判断方法
- c# – CIL – 拳击/拆箱与Nullable
- c# – 对于expr == null和expr!= null,与null的比较计算结果为true
- DBNull与Null的区别
空串与NUll串(空串和null)
空串与NUll串
public class Note {
public static void main(String[] args) {
//空串是长度为0的字符串,即 "" 是一个Java对象,长度为0和内容为空
String hello = "Hello";
String hello2 = "";
System.out.println(hello.length() == 0);//值是否是空串
System.out.println(hello2.length() == 0);//值是否是空串
hello = "Hello";
hello2 = "";
System.out.println(hello == null);//值是否是null
System.out.println(hello.length() != 0 && hello != null);//值不是空串也不是null
}
}
3-java中String值为空字符串与null的判断方法
java中String值为空字符串与null的判断方法
Java空字符串与null的区别
1、类型
null表示的是一个对象的值,而不是一个字符串。例如声明一个对象的引用,String a=null。
“”表示的是一个空字符串,也就是说它的长度为0。例如声明一个字符串String s=”“。
2、内存分配
String a=null;表示声明一个字符串对象的引用,但指向为null,也就是说还没有指向任何的内存空间。
String s=”“;表示声明一个字符串类型的引用,其值为“”空字符串,这个s引用指向的是空字符串的内存空间;
在java中变量和引用变量是存在栈中(stack),而对象(new产生的)都是放在堆中(heap):
就如下:
String str =new String(“abc”);
ps:=左边的是存放在栈中(stack),=右边是存放在堆中(heap)。
代码示例1:
String str1=null;
String str2="";
//str1==null 为true
System.out.println("str1和null的==比较结果为:"+(str1==null)); //java.lang.NullPointerException 空指针异常 System.out.println("str1的isEmpty()方法"+(str1.isEmpty())); //java.lang.NullPointerException 空指针异常 System.out.println("str2的length()方法"+(str1.length())); //java.lang.NullPointerException 空指针异常 System.out.println("str1和null的equals比较结果为:"+(str1.equals(null))); //str2==null 为false System.out.println("str2和null的==比较结果为:"+(str2==null)); //str2=="" 为true System.out.println("str2和"+""+"的==比较结果为:"+(str2=="")); //str2.isEmpty() 为true System.out.println("str2的isEmpty()方法"+str2.isEmpty()); //str2.equals(null) 为true System.out.println("str2和null的equals方法比较结果为:"+(str2.equals(null))); //str2.isEmpty() 为true System.out.println("str2的isEmpty()方法"+(str2.isEmpty())); //str2.length() 结果为0 System.out.println("str2的length()方法"+(str2.length()));
代码示例2:
String str1 = new String() ;
String str2 = null ;
String str3 = "" ;
System.out.println(str1==str2); //内存地址的比较,返回false System.out.println(str1.equals(str2)); //值的比较,返回false System.out.println(str2==str3); //内存地址的比较,返回false System.out.println(str3.equals(str2)); //值的比较,返回false System.out.println(str1==str3); //内存地址的比较,返回false System.out.println(str1.equals(str3)); //值的比较,返回true
通过以上的两个代码示例可以得出以下结论:
1 如果想调用一个方法,首先要有一个对象,但是null并不是一个对象,内存中都没有它的空间,所以null是不能够调用String中的方法的,isEmpty和length和equals方法都不能够调用。
2 字符串对象与null的值不相等,且内存地址也不相等。
3 空字符串对象与null的值不相等,且内存地址也不相等。
4 new String()创建一个字符串对象的默认值为”” (String类型成员变量的初始值为null。
java判断字符串是都为空的方法
方法1
最多人使用的一个方法, 直观, 方便, 但效率很低:
if(s == null || s.equals(“”));
方法2
比较字符串长度, 效率高, 是我知道的最好一个方法:
if(s == null || s.length() == 0);
方法3
Java SE 6.0 才开始提供的方法, 效率和方法二几乎相等, 但出于兼容性考虑, 推荐使用方法二.
if(s == null || s.isEmpty());
方法4
这是一种比较直观,简便的方法,而且效率也非常的高,与方法二、三的效率差不多:
if (s == null || s == “”);
注意:s==null是有必要存在的。
如果 String 类型为null, 而去进行 equals(String) 或 length() 等操作会抛出java.lang.NullPointerException。
并且s==null 的顺序必须出现在前面,不然同样会抛出java.lang.NullPointerException。
如以下java代码:
String s = null ;
if(s.equals("") || s == null) { System.out.println("success"); }
运行结果如下:Exception in thread “main” java.lang.NullPointerException;会提示空指针异常。
c# – CIL – 拳击/拆箱与Nullable
void C<T>(object o) where T : struct { if (o is T t) Console.WriteLine($"Argument is {typeof(T)}: {t}"); }
编译成以下CIL
IL_0000: ldarg.0 IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!!T> IL_0006: unBox.any valuetype [mscorlib]System.Nullable`1<!!T> IL_000b: stloc.1 IL_000c: ldloca.s 1 IL_000e: call instance !0 valuetype [mscorlib]System.Nullable`1<!!T>::GetValueOrDefault() IL_0013: stloc.0 IL_0014: ldloca.s 1 IL_0016: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue() IL_001b: brfalse.s IL_003c IL_001d: ldstr "Argument is {0}: {1}" IL_0022: ldtoken !!T IL_0027: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_002c: ldloc.0 IL_002d: Box !!T IL_0032: call string [mscorlib]System.String::Format(string,object,object) IL_0037: call void [mscorlib]System.Console::WriteLine(string) IL_003c: ret
但是下面的C#
void D<T>(object o) where T : struct { if (o is T) Console.WriteLine($"Argument is {typeof(T)}: {(T) o}"); }
编译成以下CIL
IL_0000: ldarg.0 IL_0001: isinst !!T IL_0006: brfalse.s IL_002c IL_0008: ldstr "Argument is {0}: {1}" IL_000d: ldtoken !!T IL_0012: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_0017: ldarg.0 IL_0018: unBox.any !!T IL_001d: Box !!T IL_0022: call string [mscorlib]System.String::Format(string,object) IL_0027: call void [mscorlib]System.Console::WriteLine(string) IL_002c: ret
我认为发生了什么:查看第一种方法的CIL,似乎(1)检查参数是否为[盒装?] Nullable< T>,如果是,则将其推入堆栈,否则为null,( 2)取消它(如果它为空?),(3)尝试获取其值,否则默认(T),(4)然后检查它是否有值,如果没有则分支出来.第二种方法的CIL足够简单,它只是试图取消打包参数.
如果两个代码的语义是等价的,为什么前一种情况涉及拆箱到Nullable< T>.而前一种情况“只是拆箱”?其次,在第一个CIL中,如果对象参数是一个盒装的int,我现在认为它正是它在tin上所说的(即盒装的int而不是盒装的Nullable< int>),不会isinst指令总是失败? Nullable< T>即使在CIL级别也能得到特殊待遇?
更新:在手写一些MSIL之后,看起来该对象(如果它确实是一个盒装的int)可以解包到int或Nullable< int>中.
.method private static void Foo(object o) cil managed { .maxstack 1 ldarg.0 isinst int32 brfalse.s L_00 ldarg.0 unBox.any int32 call void [mscorlib]System.Console::WriteLine(int32) L_00: ldarg.0 isinst valuetype [mscorlib]System.Nullable`1<int32> brfalse.s L_01 ldarg.0 unBox valuetype [mscorlib]System.Nullable`1<int32> call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() call void [mscorlib]System.Console::WriteLine(int32) L_01: ldarg.0 unBox valuetype [mscorlib]System.Nullable`1<int32> call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() brtrue.s L_02 ldstr "No value!" call void [mscorlib]System.Console::WriteLine(string) L_02: ret }
解决方法
if(o is T) //use (T)o
T t = o as T; if(t != null) //use t
对于引用类型,第一个具有冗余转换,因为is被编译为isinst和条件分支,正如您可以从使用的CIL指令中看到的那样.第二个代码与CIL方面的第一个代码相同,减去额外的(T)o cast(编译为castclass).
对于值类型,第二个选项只能以可空类型完成,我也认为它实际上比第一个慢(必须创建一个结构).
我已经将以下方法编译为CIL:
static void C<T>(object o) where T : struct { T? t = o as T?; if(t != null) Console.WriteLine("Argument is {0}: {1}",typeof(T),t); }
生成此代码:
.method private hidebysig static void C<valuetype .ctor ([mscorlib]System.ValueType) T>(object o) cil managed { // Code size 48 (0x30) .maxstack 3 .locals init (valuetype [mscorlib]System.Nullable`1<!!T> V_0) IL_0000: ldarg.0 IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!!T> IL_0006: unBox.any valuetype [mscorlib]System.Nullable`1<!!T> IL_000b: stloc.0 IL_000c: ldloca.s V_0 IL_000e: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue() IL_0013: brfalse.s IL_002f IL_0015: ldstr "Argument is {0}: {1}" IL_001a: ldtoken !!T IL_001f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_0024: ldloc.0 IL_0025: Box valuetype [mscorlib]System.Nullable`1<!!T> IL_002a: call void [mscorlib]System.Console::WriteLine(string,object) IL_002f: ret }
除了调用GetValueOrDefault之外,这正是问题中的代码,因为我没有获得可空实例的实际值.
可以为空的类型不能直接装箱或取消装箱,只能通过它们的底层值,或者作为普通的空值.第一个isinst确保其他类型不会产生异常(我想isinst !! T也可以使用),而只是一个空引用.然后,unBox.any操作码从引用中形成一个可为空的实例,然后像往常一样使用它.该指令也可以写为空检查并自行构成可空实例,但这种方式更短.
C#7使用第二种方式为T t,因此如果T是值类型,则除了使用可空类型之外别无选择.为什么不选择以前的选项呢?我只能猜测它在语义或实现,变量分配等方面可能会有一些实质性的差异.因此,他们选择与新构造的实现保持一致.
为了比较,这是我在上面的方法中改变T:struct到T:class时生成的内容(以及T?到T):
.method private hidebysig static void C<class T>(object o) cil managed { // Code size 47 (0x2f) .maxstack 3 .locals init (!!T V_0) IL_0000: ldarg.0 IL_0001: isinst !!T IL_0006: unBox.any !!T IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: Box !!T IL_0012: brfalse.s IL_002e IL_0014: ldstr "Argument is {0}: {1}" IL_0019: ldtoken !!T IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_0023: ldloc.0 IL_0024: Box !!T IL_0029: call void [mscorlib]System.Console::WriteLine(string,object) IL_002e: ret }
再次与原始方法相当一致.
c# – 对于expr == null和expr!= null,与null的比较计算结果为true
我有以下方法:
public static bool HistoryMessageExists(DBContext context,string id) { return null != context.Getobject<HistoryMessage>(id); }
在测试我的应用程序时,我看到它是不正常的 – 它为我知道的不存在于我的数据库的对象返回true.所以我停止了在方法和立即,我跑了以下:
context.Getobject<HistoryMessage>(id) null null == context.Getobject<HistoryMessage>(id) true null != context.Getobject<HistoryMessage>(id) true
Getobject的定义如下:
public T Getobject<T>(object pk) where T : DBObject,new() { T rv = Connection.Get<T>(pk); if (rv != null) { rv.AttachToContext(this); rv.IsInserted = true; } return rv; }
有趣的是,当将表达式转换为对象时,正确评估比较:
null == (object)context.Getobject<HistoryMessage>(id) true null != (object)context.Getobject<HistoryMessage>(id) false
没有平等的运算符覆盖.
编辑:事实证明有一个操作符超载,这是不正确的.但是,为什么在内部方法通用Getobject中正确评估这个方法,在这种情况下,rv的类型为HistoryMessage.
public class HistoryMessage : EquatableIdentifiableObject { public static bool HistoryMessageExists(DBContext context,string id) { var rv = context.Getobject<HistoryMessage>(id); bool b = rv != null; return b; } public static void AddHistoryMessage(DBContext context,string id) { context.InsertObject(new HistoryMessage { Id = id }); } } public abstract partial class EquatableIdentifiableObject : DBObject,IObservableObject { public event PropertyChangedEventHandler PropertyChanged; [PrimaryKey] public string Id { get; set; } //... } public abstract partial class EquatableIdentifiableObject { //... public static bool operator ==(EquatableIdentifiableObject self,EquatableIdentifiableObject other) { if (ReferenceEquals(self,null)) { return ReferenceEquals(other,null); } return self.Equals(other); } public static bool operator !=(EquatableIdentifiableObject self,null)) { return !ReferenceEquals(other,null); } return !self.Equals(other); } } public abstract class DBObject { [Ignore] protected DBContext Context { get; set; } [Ignore] internal bool IsInserted { get; set; } //... }
这里发生了什么?
解决方法
>当转换为对象时,==操作符正常工作,因为它是被使用的对象的==的实现,而不是EquatableIdentifiableObject.
>在方法Getobject中,操作符正确地求值,因为它不是EquatableIdentifiableObject的正在使用的==的实现.在C#泛型中,运行时解析(至少在这里是相关的),而不是在编译时解决.注意==是静态而不是虚拟的.所以类型T在运行时被解析,但是调用==必须在编译时解决.在编译时,当编译器解析==它不会知道使用EquatableIdentifiableObject的==的实现.因为类型T有这个约束:其中T:DBObject,new(),DBObject的实现(如果有的话)将被使用.如果DBObject没有定义==,那么将使用第一个基类的实现(直到对象).
有关EquatableIdentifiableObject的实现的更多评论==:
>您可以替换此部分:
if (ReferenceEquals(self,null)) { return ReferenceEquals(other,null); }
有:
// If both are null,or both are the same instance,return true. if (object.ReferenceEquals(h1,h2)) { return true; }
>更换更有力
public static bool operator !=(EquatableIdentifiableObject self,EquatableIdentifiableObject other) { ... }
有:
public static bool operator !=(EquatableIdentifiableObject self,EquatableIdentifiableObject other) { return !(self == other); }
>为==定义签名的方法略有误导.第一个参数命名为self,第二个命名为other.如果==是一个实例方法就可以了.由于它是一种静态方法,所以名字自身有点误导.更好的名称将是o1和o2或沿着这条线的东西,以便两个操作数在更平等的基础上对待.
DBNull与Null的区别
Null是.net中无效的对象引用。
dbnull是一个类。dbnull.Value是它唯一的实例。它指数据库中数据为空(<NULL>)时,在.net中的值。
null表示一个对象的指向无效,即该对象为空对象。
dbnull.Value表示一个对象在数据库中的值为空,或者说未初始化,dbnull.Value对象是指向有效的对象。
dbnull在DotNet是单独的一个类型 System.dbnull 。它只有一个值 dbnull.Value 。dbnull 直接继承 Object ,所以 dbnull 不是 string,不是 int,也不是 DateTime 。。。
但是为什么 dbnull 可以表示数据库中的字符串,数字,或日期呢?原因是DotNet储存这些数据的类(DaTarow等)都是以 object 的形式来储存数据的。
对于 DaTarow,它的 row[column] 返回的值永远不为 null , 要么就是具体的为column 的类型的值 。要么就是 dbnull 。 所以 row[column].ToString() 这个写法永远不会在ToString那里发生NullReferenceException,但有可能抛下标越界的异常。
dbnull 实现了 IConvertible 。 但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。
在 IDbCommand(OleDbCommand,sqlCommand...) 的ExecuteScalar的返回值中,情况可以这样分析:
select 1 这样返回的object是 1
select null 这样返回的是dbnull.Value
select isnull(null,1) 返回的是 1
select top 0 id from table1 这样返回的值是null
select isnull(id,0) from table1 where 1=0 返回的值是null
这里 ExecuteScalar 的规则就是,返回第一列,第一行的数据。如果一行都没有,那么ExecuteScalar就返回null。如果有第一行,但是第一列为空,那么返回的是 dbnull 。如果第一列第一行不为空,那么ExecuteScalar就直接对应的DotNet的值。
规则就是这样的。这里容易犯的一个错误是,把ExecuteScalar返回dbnull与null的情况混淆,例如:
string username=cmd.ExecuteScalar().ToString();
除非你认为cmd执行后,肯定至少有一行数据,否则这里就会出错。
又或者 select id from usertable where username=@name 这样的sql语句,如果找不到记录,那么ExecuteScalar则会返回null,所以千万不要
int userid=Convert.ToInt32(cmd.ExecuteScalar());
或者你会这样写 sql 语句:select isnull(id,0) from usertable where username=@name
但是 int userid=Convert.ToInt32(cmd.ExecuteScalar()); 依然会出错,因为上面的语句不成立时,仍然是不返回任何行。
对于IDbDataParameter(OleDDbParameter,sqlParameter..)的Value,如果为null,则代表该参数没有指定,或者是代表DEFAULT。如果为dbnull.Value,则代表sql中的NULL
所以,如果你要调用存储过程,里面有默认参数 @val nvarchar(20)="AABB",
那么cmd.Parameters["@val"].Value=null 代表使用这个默认的 "AABB"
而cmd.Parameters["@val"].Value=dbnull.Value 代表使用NULL来传给 @val
你可以用Convert.Isdbnull来判断一个值是否dbnull。注意Convert.Isdbnull(null)是false,也就是说null跟dbnull.Value是不等的。
关于空串与NUll串和空串和null的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于3-java中String值为空字符串与null的判断方法、c# – CIL – 拳击/拆箱与Nullable、c# – 对于expr == null和expr!= null,与null的比较计算结果为true、DBNull与Null的区别等相关内容,可以在本站寻找。
本文标签: