javase字符串(重点)
常用字符串的考察点
-
问题1:String str = new String(“xdclass.net”); 创建了几个对象
解答: 创建一个对象:常量池存在,则直接new一个对象 创建两个对象:常量池不存在,则在常量池创建一个对象,也在堆里面创建一个对象
-
问题2: 下面是比较什么?输出结果是什么?为什么是这样的结果
String str1=new String("xdclass.net"); String str2="xdclass.net"; String str3="xdclass.net"; System.out.println(str1==str2); System.out.println(str2==str3);
解答: false true 此处“==”是比较的内存地址,str1开辟了一个新的地址 str2在常量池创建,str3先在常量池查找是否有相同的了,此处有了,返回,则地址一样
-
问题3:写出下面代码的各个结果?如果需要两个都为true,应该怎么修改
String s1 = "xdclass"; String s2 = s1 + ".net"; //变量 + 常量 = 来自堆 String s3 = "xdclass" + ".net"; //常量 + 常量 = 来自常量池 System.out.println(s2 == "xdclass.net"); System.out.println(s3 == "xdclass.net");
解答: false,String s2 = s1 + ".net"; 构建了一个新的String对象,并将对象的引用赋值s2变量,常量池中的地址不一样,但是值一样 true, javac编译对【字符串常量】进行相加的表达式的优化(不用等到运行期再去进行加法运算处理,而是直接将其编译成一个这些常量相连的结果) 如果需要第一个输出为true,只需要把变量改为常量即可 final String s1 = "xdclass"; 不管是new String("XXX")和直接常量赋值,都会在字符串常量池创建.只是new String("XXX")方式会在堆中创建一个对象去指向常量池的对象,普通的常量赋值是直接赋值给变量
字符串相关构建类
String、StingBuffer与StringBuilder的区别?分别在哪写场景下使用?
解答:
三者都是final,不允许被继承
在本质都是char[]字符数组实现
String、StingBuffer与StringBuilder中,String是不可变对象,另外两个是可变的
StringBuilder 效率更快,因为它不需要加锁,不具备多线程安全
StringBuffer里面操作⽅方法用synchronized ,效率相对更低,是线程安全的;
使用场景:
操作少量的数据用String,但是常改变内容且操作数据多情况下最后不要用String,因为每次生成中间对象性能会降低
单线程下操作大量的字符串用StringBuilder,虽然线程不安全但是不影响
多线程下操作大量的字符串,且需要保证线程安全,则用StringBuffer
面向对象篇
面向对象的四大特性是什么?分别解释下
解答:
抽象
abstract声明的类,声明的方法
比如开发一个支付系统,要对接很多的支付网关,很多第三方网关,
一般支付有个pay(金额,订单号)方法,pay方法可能传入金额、订单号,要调用很多具体的实现,可以声明抽象一个支付方法,具体的一个实现,可能有很多种,可能有一个默认的是实现是本地支付,也可以通过一个抽象之后,别人可以具体去实现,你可以调用微信支付、支付宝支付、银行卡支付,pay方法有很多实现,抽象可以把公共的属性抽取出来,别人可以继承
封装
就是把过程和数据包围起来,对数据的访问只能通过自己实现的接口,常见的封装会有一些关键字,比如private/protected/public
封装就是把所有的对象组合起来,定义如何去使用
让代码更容易理解和维护,加强了安全性
类封装、方法封装
继承
具有公共的方法和属性
动物 《- 猫
动物 《- 狗
abstract class AbsPay{}
WeixinPay extends AbsPay{}
AliPay extends AbsPay{}
多态
同一个行为具有不同的表现形式的能力
代码:减少耦合、灵活可拓展