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# 中都是报错的. 应该是在拆箱的时候,会严格检查类型.