一、String
怎么比较两个字符串的值一样,怎么比较两个字符串是否同一对象(equals和==比较的区别)
==
基本类型:比较值
引用类型:比较地址
equals
比较类型:默认比较地址。 可自定义比较内容
public void test_string() {
String s1 = new String("java");
String s2 = new String("java");
System.out.println("s1==s2:"+(s1==s2)); // false
System.out.println("s1.equals(s2):"+s1.equals(s2)); //true
String s3 = "java";
System.out.println("s1==s3:"+(s1==s3)); //false
System.out.println("s1.equals(s3):"+s1.equals(s3)); //true
String s4 = "abc"; //在常量区创建 abc, 用s4引用
String s5 = "abc"; // 常量区已存在abc,直接用s5引用
System.out.println("s4==s5,s4.equals(s5):"+(s4==s5)+","+s4.equals(s5)); // true, true
String s6 = "abc" + "abc"; // 在常量区创建 abcabc,用s6引用
}
switch中可以使用String吗
JDK7+可以
String str = new String("abc");创建了几个对象,为什么?
两个,一个是"abc",一个是new String() 出来的str
但是 String s1 = "abc"; String s2 = "abc"就只会创建一个对象,推荐这种写法
注:
只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,对此我们不再赘述。因此我们提倡大家用引号包含文本的方式来创建String对象以提高效率
String、StringBuffer、StringBuilder有什么区别?
对于 String str = ""; for(int i=0; i<10; i++) { str += "abc"},将会有创建十次对象,不推荐这种写法
( String str += "abc" 会被编译器优化成 StringBuilder str = new StringBuilder(); strt.append("abc") ;)
上面可改写为:
StringBuilder str = new StringBuilder(); for(int i=0; i<10; i++) { str.append("abc")} 则总共只会创建一次对象
而StringBuffer功能跟StringBuilder是一样的,只不过在前面多了synchronized保证线程安全。
String.trim()方法去掉的是哪些字符?
trim()方法实际上trim掉了字符串两端Unicode编码小于等于32(\u0020)的所有字符。
注:substring()返回新对象
String可以被子类继承吗?
不可以,因为被final修饰
可以自定义java.lang.String类并使用吗?
https://blog.csdn.net/u013206465/article/details/47170253
https://blog.csdn.net/xiongyouqiang/article/details/79151903
可以自定义一个String,通过自定义类加载器来加载,但是自定义String的包名不能叫java.lang.String
String与byte[]两者相互之间如何转换?
public void test_string_2_byte() {
String str = "java";
byte[] byteArr = str.getBytes();
for(int i=0; i<byteArr.length; i++) System.out.print(byteArr[i]+",");
}
输出 106,97,118,97,
public void test_byte_2_string() {
byte[] bytes = {106,97,118,97};
String str = new String(bytes);
System.out.println(str);
}
输出:java
二、类初始化顺序
单个类的初始化顺序 : 静态变量 > 静态初始块 > 成员变量 > 非静态初始块 > 构造函数
public class Main {
public static String staticFiled = "static field";
static {
System.out.println(staticFiled);
System.out.println("static block");
}
private String field = "member field";
{
System.out.println(field);
System.out.println("non-static block");
}
public Main() {
System.out.println("constructor");
}
public static void main(String[] args) {
Main app = new Main();
}
输出
static field
static block
member field
non-static block
constructor
类继承初始化顺序
public class Parent {
private static String parentStaticField = "parent static field";
static {
System.out.println(parentStaticField);
System.out.println("parent static block");
}
private String parentField = "parent member field";
{
System.out.println(parentField);
System.out.println("parent non-static block");
}
public Parent() {
System.out.println("parent constructor");
}
}
public class Main extends Parent {
private static String childStaticField = "child static field";
static {
System.out.println(childStaticField);
System.out.println("child static block");
}
private String childField = "child member field";
{
System.out.println(childField);
System.out.println("child non-static block");
}
public Main() {
System.out.println("child constructor");
}
public static void main(String[] args) {
Main app = new Main();
}
}
输出
parent static field //父类静变量
parent static block //父类静态代码块
child static field //子类静态变量
child static block //子类静态代码块
parent member field //父类成员变量
parent non-static block //父类非静态代码块
parent constructor //父类构造函数
child member field //子类成员变量
child non-static block //子类非静态代码块
child constructor //子类构造函数
从上面两个例子可以看出,父类的静态变量和静态初始块肯定是先于子类加载的
同一个类中的静态变量和代码块初始化顺序:用定义变量的顺序决定
public class Main {
private static A a = new A();
static {
System.out.println("static block");
}
private static B b = new B();
public static void main(String[] args) {
Main app = new Main();
}
}
class A {
public A() {
System.out.println("static A");
}
}
class B {
public B() {
System.out.println("static B");
}
}
三、interface和abstract
JDK8
主要区别: 构造器,实例化,public修饰,多继承,子类强制实现方法
四、泛型
List<String> list = new ArrayList<String>(); 推荐写法
1.类型擦除
下面代码输出什么?
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass()); // true
2.泛型方法和普通方法
public class Test1<T>{
//泛型类中的普通方法
public T testMethod(T t){
return t;
}
//泛型方法
public <T> T testMethod1(T t){
return t;
}
}
注意只有修饰符后紧跟 <T>才叫泛型方法, 例如 public <T> void func()是泛型方法,而 public T func();不是泛型方法
通配符
泛型类中的静态方法不中不能使用泛型T(但是可以单独申明泛型)
不能通过编译