java基础
常量缓存池
Integer integer = new Integer(18);
Integer integer1 = new Integer(18);
Integer integer2 = Integer.valueOf(18);
Integer integer3 = Integer.valueOf(18);
//false
System.out.println(integer == integer1);
//true
System.out.println(integer2 == integer3);
基本数据类型除了Double,Float之外,其他六个包装类(Byte,Integer,Short,Character ,Boolean,Long)都有常量缓冲池
- Byte -128~127
- Short -128~127
- Integer -128~127
- Long -128 ~127
- Character:\u0000 - \u007f 0 ~128
- Boolean: true and false
拿Integer举例子,Integer类内部内置了256个Integer类型的缓存数据,当使用的数据范围在-128127之间时,会直接返回常量池中数据的引用,而不是创建对象,超过这个范围会new一个对象,18在这个-128127之间,300不在.
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
可以看出是因为IntegerCache这个静态内部类,让我们看一下源码
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
如果使用new Integer()创建对象,即使值在-128~127范围内也不会被缓存,.每次都会创建新的对象.因此推荐使用Integer.valueof()方法获得整数对象.
静态代码块通常用来初始化一些静态变量,它会优于main()方法执行
可以通过命令来设置缓存值大小,当然是不能无限大
String类
- String类是final的,意味着他不能被继承
- String类实现了Serializable接口,意味着它可以被序列化
- String类是实现了Compareble接口,意味着最好不要用'=='来比较两个字符串是否相等,应该用compareTo()方法比较,如果只是比较内容可以用String类的equals方法
- String,String buffer 和String builder一样都实现了CharSequence接口,他们三属于近亲 .CharSequence接口是一个可读序列的字符的接口,实现了CharSequence接口的类可以提供对字符序列的访问和操作
- java9 以前Sting是用char型数组实现,之后改成byte型数组实现,并增加了coder来表示编码.好处是在Latin1字符为主的程序里,可以把String占用的内存减少一班,这个改进也增加了编码的检测
- 每个字符串都会有一个hash值,这个哈希值大概率不会重复的,因此String很适合作为HashMap键值
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
hashcode方法首先检测是否已经计算过哈希码,如果已经计算过,则直接返回缓存的哈希码.否则循环遍历字符串的所有字符,并使用一个公式计算哈希码,将得到的哈希值存储在hash成员变量中,以便下次调用hashcode方法直接返回该值,而不需要从新计算.这是一种缓存优化,称为"惰性计算".
hashmap添加一个新对象时:
- 计算对象的哈希值
- 和之前的哈希值进行比较,如果不相等直接存进去
- 如果已经相等,在调用equals()进行比较,如果相等不存了
- 如果不等,说明哈希冲突了,增加一个链表,存放新的对象
- 如果链表的长度大于8,转为红黑树处理
也就是说:
- 两个对象调用equals()为真,hashcode()肯定为真
- 两个对象调用hashcode()为假,equals()肯定为假
- 两个对象调用equals()为假,调用hashcode()的值不一定不一样
- 两个对象调用hashcode()得到的结果相等,equals()值不一定为true
String为什么不可变
- 可以保证数据的安全性,避免被篡改,比如用户密码.
- 保证哈希值不会频繁变更
String常量池
//会创建3个对象,1个字符串常量池,2个堆上
String str = new String("豪哥");
String str2 = new String("豪哥");
//只会创建一个对象,字符串常量池
String s = "妹妹";
String s2 = "妹妹";
new 的方式始会创建1个对象,不管字符内容是否已经存在,而双引号方式会重复利用字符常量池中已经存在的对象
多线程基础
what?
解释什么是线程必须先说明什么是进程,程序在操作系统中就是一个进程(占用内存资源),线程是进程创造的,一个进程可以有多个线程
how?
在java中有3种创建多线程的方式
// 1,继承thread类
class [class name] extends Thread
// 2,实现runnable接口
class [class_name] implements Thread
main(){
new Thread(new [class_name] ).start
}
//3.获得返回值多线程
...
线程同步
多线程在访问同一个资源时候容易出每个对象都有自己互斥锁标识,通过synchronized 标识绑定形成锁
网络编程
端口号:标识计算机某个特定的网络程序
标签:java,String,int,127,基础,哈希,Integer,new From: https://www.cnblogs.com/lz2z/p/17704261.html