一些注意的东西

来源:互联网 发布:长沙企业名录数据库 编辑:程序博客网 时间:2024/05/21 11:29

1 字符串,

Java 中字符串== 是比较地址值, 是否是同一个对象, Equals 是比较字符序列是否一样. C# 中因为重写了== 方法所以, 不论是== 还是Equals 还是String.Equals(str,str2) 比较的都是字符序列, 只有String.ReferenceEquals(str,str1) 比较的才是地址值.

Java 中字符串常量池, 只会记录常量, 以下这种就不会记录, 例如 String s ="1", String s1="2"; String s3=s+s2;  常量池中不会有"12" 的字符串.

Java 中的"str".intern() 方法返回的是常量池中记录的跟str字符序列一致的字符串. 但是如果此时常量池中并没有这个字符串的话, 那么就有两种可能了在JDK 1.7 以前, 会直接把str 这个字符串在常量池中也弄一份, 然后返回这个地址值, 所以此时str==str.intern() 返回false. 但是JDK 1.7以后, 常量池从PermGen中移到了堆中, 所以这种情况下, 会直接记录str在堆中的地址, 然后返回, 所以str==str.intern() 返回为True, 而且再创建String str4="str"  str4==str 返回的也是true. 因为此时常量池中已经有了, 而且就是最开始的那个str. 至于常量池中怎么记录那个str对应的字符串的地址的就不知道了.


还有一点是Java中string重写了hashcode 方法, 所以如果要获取真正的跟地址值相关的hash值应该调用System.IdentityHashCode(str) 这个方法.


2. Java中的复合运算

Java中 byte a = 10; a+=10;不会报错, 在C# 中也不会报错,  但是byte a = 10; a+=0.5f; 这一段代码在Java中不报错, 会直接强转, 但是在C# 中则会报错

3. 一个强转的问题

int a =10; Object o = a; float b = (flaot)o;   这一段强转, 无论在Java还是C# 中都是报错的, 


4.Java 中的静态同步方法

Java中的静态同步方法跟以这个类对象为锁的同步代码块, 也会产生锁的效果. 也就是说多个线程来运行的话, 也会一次只能一个线程运行. 尽管这他妈都已经不是同一个方法了.


5. 类的初始化

Java 中的类的初始化会有下面几种情况(一个线程访问当前类的静态属性的时候)

一, 该类没有初始化, 那么当前线程会去初始化这个类

二, 该类正在被当前线程初始化, 那就不做什么了, 接着等吧,

三, 该类正在被别的线程初始化, 那就只能放弃CPU 的执行权, 等待别的线程把这个类初始化好

四, 该类已经被初始化好, 那就直接获取那个属性


6,不序列化某个字段

在Java中是用transient 关键字修饰, 在C# 中的加上[NonSerialized] 标签. 序列化的话, Java中是实现Serializable 接口, C# 中是加上[Serializable] 标签. 真正序列化的时候Java是用对象输出流,  C# 中是用BinaryFormatter. 


7. Java 中的final 和C# 中的readonly

Java中的final属性修饰的字段, 必须初始化 而且初始化的话只能在构造函数, 显示初始化和构造代码块中, 静态的final属性只能在静态代码块和显示初始化

C# 中的readonly修饰的字段可以不用初始化, 也可以正常访问, 会有默认初始值, 初始化只能在构造函数, 和显示初始化, C# 中没有构造代码块. 静态的readonly字段的话只能在显示初始化或者是静态构造函数中, 静态构造函数 不能加任何修饰词. Java中的静态代码块也是这样. final 可以修饰局部变量, 但是readonly是不可以修饰局部变量的, 但是const可以


8.方法

非静态方法在方法区中也是唯一的, 并不是每创建一个对象就存一个方法.  但是为什么不同的对象调用同一个方法会不一样呢/ 因为对于每一个非静态方法而言, 默认的第一个参数就是this, 就是调用这个方法的对象, 对于静态方法而言则没有这个东东了.     所以方法的调用不一定要保证对象存在. 可以没有任何对象, 但是调用这个方法, 只要方法中没有使用到this所含有的东西就可以了.     所以在C# 中一个委托在添加方法的时候, 如果添加的是非静态方法的话则必须要对象调用. 例如   delegate void show(), show s.    class  Man, void mtd();  ? 如果要添加mtd 这个方法的话, 则是Man m = new Man(). s+=m.mtd;  静态的话就是s+=Man.mtd 这样子.


9, delegate 和event

 delegate 修饰的普通的委托, 可以在外部进行调用, 但是event修饰的事件就不能了, 在外部只能调用+=或者-= 这样的方法, 但是一样都是可以通过+= 添加多个方法, 记住, 可以重复添加同一个方法, 并不会覆盖, 


10, Unity中序列化一个私有属性

可以使用[SerializedField], 把某个属性在属性面板上添加一个header 可以使用[header("name")],  要序列化一个对象, 只需要把这个类标记为[Serializable] 就可以了., 使用多个标签可以用, 逗号隔开


11. float  加

 在Java中float a =999999999, syso(a==a+20) 返回是true 因为精度丢失比较大.  但是在C# 中没有这个问题, 即便是a==a+1 返回也是false.


12, 一个强转的问题

int a =10; Object o = a; float  b = (float)o; 这个代码无论在Java还是C# 中都是报错的.  应该是在拆箱的时候,会严格检查类型.

原创粉丝点击