1、String的两种创建方式以及存储方式
- 第一种:双引号方式
x和y都是指向同一个内存地址,他们的引用都是指向方法区的同一个内容。同一个String字面值无论被创建多少次,始终只有一个内存地址被分配,之后的都是这个String的拷贝,在java中称作“字符串驻留”。这种方式创建的时候首先会查看字符串池中是否已经存在,存在就直接返回PermGen中的该String对象,否则就会创建一个新的String对象,之后再放进字符串池中。
String x = "abcd";
String y = "abcd";
System.out.println(x==y);//true
System.out.println(x.equals(y));//true
- 第二种:构造器方式
a==b 为false 是因为通过new 构造器的方法创建之后,在heap堆中分别分配了两个内存地址。a 和 b 分别指向了堆中的两个不同的对象,不同的对象就会有不同的地址分配。
String a = new String("abcd");
String b = new String("abcd");
System.out.println(a==b);//false
System.out.println(a.equals(b));//true
2、Java中是值传递还是引用传递?
是值传递。
值传递:会创建副本,在函数中无法改变原始对象;
引用传递:不创建副本,在函数中可以改变原始对象。
3、Java内存区域
- 方法区(线程共享)
- 堆(线程共享)(会溢出)
- 栈(会溢出)
- 本地方法栈
- 程序计数器(不可能溢出的只有PC)
4、final的作用和用法
- 修饰类不能被继承;
- 修饰方法不能被重写,JVM会尝试将其内联,提高运行效率
- 修饰变量不能被改变
- 修饰的常量会在编译阶段存入常量池
- 修饰引用则引用不可变,但是引用指向的内容可变
5、static修饰符
- 修饰的类是静态内部类
- 修饰的方法是静态方法,不能被重写。该方法是属于当前类的,而不属于某个对象,可以直接使用类名来调用。在该方法中不能使用this或者super关键字
- 修饰的变量是静态变量,被所有实例所共享,不会依赖于对象。静态变量在内存中只有一份拷贝,在JVM加载类的时候,只会被分配一次内存
- 修饰的代码块叫静态代码块。静态代码块中的代码在整个类加载的时候只会执行一次。
6、深拷贝和浅拷贝
深拷贝:将要复制对象所引用的对象也复制了
浅拷贝:仅仅复制所考虑的对象,不复制所引用的对象
7、创建线程的方式
- 继承Thread类,重写run方法
多个线程间无法共享线程类的实例变量,需要创建不同Thread对象
/**
* 通过继承Thread实现线程
*/
public class ThreadTest extends Thread{
private int i =