Java对异常进行了分类,不同类型的异常分别使用了不同的Java类表示,所有异常的父类为java.lang.Throwable,Throwable类下面派生了两个子类:Error和Exception,Error表示应用程序本身无法克服和恢复的一种严重问题;Exception表示程序还能够克服和恢复的问题,其中Exception又分为系统异常和普通异常,系统异常是软件本省缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组下标越界异常(ArrayIndexOutOfBoundException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是软件运行环境的变化或者异常所导致的问题,是用户可以克服的问题,比如网络断线、磁盘空间不足等,发生这样的异常时,程序不应该死掉。
Java为系统异常和普通异常提供了不同的解决方案,编译器要求普通异常必须使用try…catch处理或者throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常****可以处理也可以不处理,编译器不强制使用try…catch处理或者throws声明,所以系统异常也称为unchecked异常。
public class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program"+ "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2);
System.out.println(s1 == s5);
System.out.println(s1 == s6);
System.out.println(s1 == s6.intern());
System.out.println(s2 == s2.intern());
}
}
依次输出:false、true、false、true、false。s1和s2分别是两个不同对象的引用,这个两个对象里面的内容相同,但却不是一个对象,所以地址不同,第一个为false,无需过多解释;利用+直接连接两个字符串常量,虚拟机会直接把这两个字符串连接起来看成一个字符串,所以s1 == s5返回true;利用+连接两个引用,虚拟机看成StringBuilder,会创建一个StringBuilder对象,然后调用append方法进行追加操作,最后调用toString方法转换成String,所以s1 == s6返回false; String对象的intern()方法会得到字符串对象在常量池中对应的版本的引用(前提是常量池中已有一个字符串与String对象的equals结果为true),所以s1 == s6.intern()返回true;同理,s2.intern()是和s6.intern()相同的,所以最后一个的执行结果是false,因为s1 == s2返回的就是false。
byte 1 boolean 1
short 2 char 2
int 4 float 4
long 8 double 8
比较记忆会更快噢。注意:String不是基本数据类型,String是引用类型,String的底层是使用char数组实现的。
前者不正确,后者正确。对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算的结果也是int类型,需要强制类型转换后才可以赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1 += 1;相当于s1 = (short)(s1 + 1),里面已经包含了强制类型转换。
Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类,为了可以将这些基本数据类型当成对象来操作,Java为每一个基本数据类型都又引入了对应的包装类型,int的包装类型就是Integer。从Java5开始又引入了自动装箱/拆箱机制,使得二者可以相互转换。
原始类型:boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
自动装箱/拆箱机制:
Integer a = new Integer(3);
Integer b = 3; //自动装箱为Integer类型
int c = 3;
System.out.println(a == b); //输出false,两个引用没有指向同一个对象
System.out.println(a == c); //true,**自动拆箱成int类型进行比较**
Integer f1 = 100,f2 = 100,f3 = 150,f4 = 150;
System.out.println(f1 == f2);
System.out.println(f3 == f4);
输出:true,false。首先需要注意的是,f1,f2,f3,f4都是包装类型,所以使用**==运算符比较的不是值**,而是引用。当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,查看valueOf源码我们可以知道,对于整型字面量的值在-128到127之间那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面第一行输出true,第二行由于150大于了128,故输出false。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
(越是简单的面试题,里面的玄机就越多,需要面试者相当深厚的基础功)
int length():返回当前字符串的长度
int indexOf(int ch/String str):用于查找当前字符串中字符或子串,返回字符或子串在当前字符串中从左边起首次出现的位置,若没有出现则返回-1。
int indexOf(int ch/String str, int fromIndex):与上一种类似,区别在于该方法从fromIndex位置向后查找。
int lastIndexOf(int ch/String str):类似,区别在于该方法从字符串的末尾位置向前查找
int lastIndexOf(int ch/String str, int fromIndex):类似,区别于该方法从fromIndex位置向前查找。
String toLowerCase():返回将当前字符串中所有字符转换成小写后的新串
String toUpperCase():返回将当前字符串中所有字符转换成大写后的新串
String replace(char oldChar, char newChar):用字符newChar替换当前字符串中所有的oldChar字符,并返回一个新的字符串。
String replaceFirst(String regex, String replacement):该方法用字符replacement的内容替换当前字符串中遇到的第一个和字符串regex相匹配的子串,应将新的字符串返回。
String replaceAll(String regex, String replacement):该方法用字符replacement的内容替换当前字符串中遇到的所有和字符串regex相匹配的子串,应将新的字符串返回。
String trim():截去字符串两端的空格,但对于中间的空格不处理。
char charAt(int index):获取字符串中指定位置的字符。
String[] split(String regex):将regex作为分隔符进行字符串分解,分解后的字字符串在字符串数组中返回。
字符串转为基本数据类型:调用基本数据类型对应的包装类中的方法parseXXX(String)或者valueOf(String)既可以返回相应的基本数据类型。
基本数据类型转字符串:一种方法是将基本数据类型与空字符串("")连接(+)即可获得对应的字符串,另一种方法是调用String类中的valueOf()方法返回相应字符串。
按照流的方向:输入流(inputStream)和输出流(outputStream);
按照实现的功能分:节点流(可以从或向一个特定的地方(节点)读写数据,例如FileReader)、处理流(是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据的读写,例如BufferdReader,处理流的构造方法总是要带一个其他流对象做参数。一个流经过其他流的多次封装,成为流的链接)
按照处理的数据的单位可以分为字节流和字符流。字节流继承于InputStream和OutputStream,字符流继承于InputStreamReader和outputStreamReader。
String:字符串常量,再修改时本身不会改变,如修改等于重新生成一个新的字符串对象,String定以后不可改变,故是线程安全的。
StringBuffer:在修改时会改变对象自身,每次修改操作都是对StringBuffer对象本身进行修改,不是生成新的对象,适用于需要经常改变字符串的情形下,由于实现synchronized同步锁(故效率稍慢),是线程安全的,也适用于多线程环境下。
StringBuilder:功能和StringBuffer基本一样,只是没有实现同步锁,不是线程安全的,适用于单线程环境下,执行效率较高。
原文:https://blog.csdn.net/qq_21583077/article/details/88196780