
内部类和静态内部类的区别
内部类:
1、内部类中的变量和方法不能声明为静态的。
2、内部类实例化:B是A的内部类,实例化B:A.B b = new A().new B()。
3、内部类可以引用外部类的静态或者非静态属性及方法。
静态内部类:
1、静态内部类属性和方法可以声明为静态的或者非静态的。
2、实例化静态内部类:B是A的静态内部类,A.B b = new A.B()。
3、静态内部类只能引用外部类的静态的属性及方法。
inner classes——内部类
static nested classes——静态嵌套类
其实人家不叫静态内部类,只是叫习惯了,从字面就很容易理解了。
内部类依靠外部类的存在为前提,而静态嵌套类则可以完全独立,明白了这点就很好理解了。
非静态内部类中的变量和方法不能声明为静态的原因
静态类型的属性和方法,在类加载的时候就会存在于内存中。使用某个类的静态属性和方法,那么这个类必须要加载到虚拟机中。但是非静态内部类并不随外部类一起加载,只有在实例化外部类之后才会加载。
我们设想一个场景:在外部类并没有实例化,内部类还没有加载的时候如果调用内部类的静态成员或方法,内部类还没有加载,却试图在内存中创建该内部类的静态成员,就会产生冲突。所以非静态内部类不能有静态成员变量或静态方法。
String,StringBuilder,StringBuffer的区别
- String 字符串常量
- StringBuffer 字符串变量(线程安全)
- StringBuilder 字符串变量(非线程安全)
性能上通常StringBuilder > StringBuffer > String。
String是不可变对象,每次对String类型进行改变的时候都等同于生成了一个新的String对象,然后将指针指向新的String对象,所以性能最差,对于要经常改变内容的字符串不用String。
StringBuffer是字符串变量,对它操作时,并不会生成新的对象,而是直接对该对象进行更改,所以性能较好。
StringBuilder和StringBuffer一样,是字符串变量,但是他不带有synchronized关键字,不保证线程安全,所以性能最好。在单线程的情况下,建议使用StringBuilder。
总体来说:
- String:适用于少量的字符串操作的情况。
- StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况。
- StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况。
来一些问题:
下面这段代码的输出结果是什么?
String a = "helloworld";String b = "hello" + "world";System.out.println((a == b));
输出结果为:True。
原因是String对字符串的直接相加,会在编译期进行优化。即hello+world在编译时期,被优化为helloworld,所以在运行时期,他们指向了同一个对象。我们也可以推理,对于直接字符串的相加,String不一定比其余两个慢。
下面这段代码的输出结果是什么?
String a = "helloworld";String b = "hello"; String c = b + "world"; System.out.println((a == c));
输出结果为:False。
原因是c并非两个字符串直接相加,包含了一个字符串引用,这时不会做编译期的优化。所以a、c最终生成了两个对象,这时他的效率低。
集合和数组之间的相互转换
数组变集合:
通常我们会回答的是以下代码:
List list = Arrays.asList(array);
但这并不是很好的答案,此时组合成的list是Arrays里面的一个静态内部类,该类并未实现add、remove方法,因此在使用时存在问题。
可以这样:
String array[]= {"hello