String、StringBuffer和StringBuilder
- String类对象中存储的内容初始化后不能改变,StringBuffer和StringBuilder可以改变。
- StringBuilder性能更快,不实现线程安全功能
- StringBuffer和StringBuilder的对象不能直接输出。
toString()
方法将StringBuffer,StringBuilder对象转换为String字符串append()
方法用于在字符串的后面追加字符串
查看代码执行时长:
long start = System.currentTimeMillis(); //获取当前时间戳(ms)
// ...
long end = System.currentTimeMillis(); //获取当前时间戳(ms)
System.out.println("代码执行时间:" + (end - start) + "ms");
str = str + “a”
编译器会处理为
new StringBuilder().append(str).append(“a”)
- 循环很多次的字符串拼接最好用append,不然会new太多对象,导致频繁的GC。
- 如果是少量的小字符串叠加,那么采用append()提升效率并不明显,但是遇到大量的字符串叠加或者大字符串叠加的时候,使用append()的效率会高很多。
基本数据类型和包装类
- Java中一共8种基本数据类型(开头小写),都对应有包装类(开头大写)。
- 装箱:将基本类型(在栈中分配内存)变成对象(堆中分配内存)。本质上是,编译器编译时自动添加:
Integer i = new Integer(100);
- 拆箱:包装类对象自动转换成基本数据类型。如:
int a = new Integer(100);
- 字符串与基本类型的相互转换中,用到字符串的
valueOf()
方法、包装类Integer的parseInt(String)
等方法
String 和 new String()的区别
new String()
不会访问字符串池,而是先在堆中开辟空间。String str = "abc";
的话会先访问字符串池看有没有一样的,有的话就不分配堆内存了,不同的引用指向字符串池中的一个地址。==
比较的是引用的地址。equals()
方法可以比较的是引用指向的字符串的内容。(对于指向其他对象的引用,如果要判断内容是否相同必须自己写代码)
String a="Tom";
String b=new String("Tom");
String c="Tom";
String d="T";
String e=d+"om";
System.out.println(a==b); //结果为false
System.out.println(a==c); //结果为true
System.out.println(a==d); //结果为false
System.out.println(a==e); //结果为false
JVM中的内存管理
- 每一个JVM进程都对应一个Runtime实例,此实例是由JVM为其实例化的。所以我们不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用。
- 失去引用的对象会被回收。
- GC的时机是不可预测的,可能是定时的,可能是内存不足的时候,取决于JVM的实现。
Runtime.getRuntime().gc();
可以建议JVM走到这里的时候回收垃圾,不过JVM不一定会听你的。- 一般垃圾回收的时候会暂停主程序运行,所以不要频繁GC。
- 三个内存分区:栈区、堆区、方法区。栈不需要GC(调用时划分栈帧,调用结束回收栈帧)。堆区和方法区都会GC。
- 栈里放基本数据类型和引用类型;堆里放对象的实例;方法区放代码和静态变量。
- 栈记录了线程的方法调用。每个线程拥有一个栈。在某个线程的运行过程中,如果有新的方法调用,那么该线程对应的栈就会增加一个存储单元,即帧(frame)。在frame中,保存有该方法调用的参数、局部变量和返回地址。
finalize()
方法不等于析构函数。- C++的析构函数用来做一些必要的工作,例如释放掉指针成员所指向的对象所占的内存,因为C++没有java的垃圾回收器,所有new出来的对象,都要显式地delete掉,避免内存泄漏。
- Java中 一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法进行一些必要的清理工作(不晓得具体是什么)。只有到真正进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间。
protected void finalize() throws Throwable {
System.out.println("我被垃圾回收了!");
}
接口
某个接口类型的引用变量可以指向实现了该接口的类的对象
网络编程
- URI类可以解析URI。URI不一定可以定位一个资源,URL才可以。但是URI确实是一个资源的代号。URL是可以定位资源的URI。
- 一个IP对应一个主机。一个端口对应一个主机上的一个进程。
- 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,因此建立网络通信连接至少要一对socket(server 和 client)。
- socket的英文原义是"孔"或"插座"。socket本质是编程接口(API)
//在服务器端
ServerSocket server = new ServerSocket(端口号);
Socket client = server.accept();
//在客户端
Socket socket = new Socket(主机地址, 端口号); //server.accept()把客户端的socke返回给服务器噢
- TCP/IP协议会建立链接通路,UDP协议不会,也没有服务器和客户端的概念。
流
- I/O流类名后缀Stream的是字节流,后缀Reader/Writer的是字符流
- 字节流可用于二进制文件读写;字符流用于文本文件读写
- 文本文件需要特定字符编码格式转码,否则会出现乱码。