本文共 14674 字,大约阅读时间需要 48 分钟。
public final class String implements java.io.Serializable, Comparable, CharSequence //String类实现了Serializable,表示字符串是支持序列化的 //Comparable ,可以比较大小 //CharSequence
private final char value[];//String内部定义了final char value[]数组,用于存储字符内容
//通过字面量的方式(区别于new)给字符串赋值时,此时的字符串声明在字符串常量池中(方法区);public static void main(String[] args) { String s1="hello";//字面量定义方式 String s2="hello";//s1、s2都指向常量池中的"hello" System.out.println(s1==s2); s1="hi";//s1指向"hi","hello"不受影响}
字符串不可变性:
当对字符串变量重新赋值时,要重新指定内存区赋值生成,不会改变原有的字符串常量的值;
进行字符串连接操作时,也要重新指定内存区生成新的字符串;
调用replace()方法修改字符串是也必须要重新指定内存区生成新的字符串;
new方式创建字符串对象
s1="hac";String s3=new String("hac");String s4=new String("hac");System.out.println(s1==s3);//falseSystem.out.println(s3.equals(s4));//true//"hac"仍然存储在方法区;//s3指向堆空间的地址;//堆空间存放的是方法区的字符串的地址;System.out.println(s1==s3);
当对象的属性中有字符串时,在堆中的实体对象中存储着字符串的地址
Person person=new Person("hac");System.out.println(s3.equals(person.name));//true
注:
1.常量与常量拼接时,结果存放在常量池,不会出现相同的常量;
2.由变量与常量拼接时,拼接结果存放在堆中;
3.拼接的结果如果使用intern()方法,返回值在常量池中;
intern()方法是一个本地方法,它会从字符串常量池中查询当前字符串是否存在,如果存在,就直接返回字符串常量池中的当前字符串;如果不存在就会将调用方法的字符串放入常量池中,然后返回字符串;
SN(序号) | 方法描述 |
---|---|
1 | 返回指定索引处的 char 值。 |
2 | 把这个字符串和另一个对象比较。 |
3 | 按字典顺序比较两个字符串。 |
4 | 按字典顺序比较两个字符串,不考虑大小写。 |
5 | 将指定字符串连接到此字符串的结尾。 |
6 | 当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。 |
7 | [static String copyValueOf(char 返回指定数组中表示该字符序列的 String。 |
8 | [static String copyValueOf(char 返回指定数组中表示该字符序列的 String。 |
9 | 测试此字符串是否以指定的后缀结束。 |
10 | 将此字符串与指定的对象内容比较。 |
11 | 将此 String 与另一个 String 比较,不考虑大小写。 |
12 | [byte 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
13 | [byte 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
14 | [void getChars(int srcBegin, int srcEnd, char 将字符从此字符串复制到目标字符数组。 |
15 | 返回此字符串的哈希码。 |
16 | 返回指定字符在此字符串中第一次出现处的索引。 |
17 | 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。 |
18 | 返回指定子字符串在此字符串中第一次出现处的索引。 |
19 | 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 |
20 | 返回字符串对象的规范化表示形式。 |
21 | 返回指定字符在此字符串中最后一次出现处的索引。 |
22 | 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。 |
23 | 返回指定子字符串在此字符串中最右边出现处的索引。 |
24 | 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 |
25 | 返回此字符串的长度。 |
26 | 告知此字符串是否匹配给定的正则表达式。 |
27 | 测试两个字符串区域是否相等。 |
28 | 测试两个字符串区域是否相等。 |
29 | 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 |
30 | 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
31 | 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 |
32 | [String 根据给定正则表达式的匹配拆分此字符串。 |
33 | [String 根据匹配给定的正则表达式来拆分此字符串。 |
34 | 测试此字符串是否以指定的前缀开始。 |
35 | 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 |
36 | 返回一个新的字符序列,它是此序列的一个子序列。 |
37 | 返回一个新的字符串,它是此字符串的一个子字符串。 |
38 | 返回一个新字符串,它是此字符串的一个子字符串。 |
39 | [char 将此字符串转换为一个新的字符数组。 |
40 | 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 |
41 | 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。 |
42 | 返回此对象本身(它已经是一个字符串!)。 |
43 | 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 |
44 | 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。 |
45 | 返回字符串的副本,忽略前导空白和尾部空白。 |
46 | 返回给定data type类型x参数的字符串表示形式。 |
47 | 判断是否包含指定的字符系列。 |
48 | 判断字符串是否为空。 |
1.调用包装类的静态方法parseXxx(String str)使String类对象转换为基本数据类型、包装类
String str="666";int num=Integer.parseInt(str);System.out.println(num);
2.调用String类中的重载方法valueOf(xxx)使xxx转换为String类对象
String str2=String.valueOf(num);
1.调用String类中的toCharArray()方法使String转换为char[]数组
String str="hac";char[] arr=str.toCharArray();System.out.println(Arrays.toString(arr));
2.调用String类构造器使char[]数组转换为String类对象
String str2=new String(arr);
1.调用String的getBytes()方法使String对象转换为byte[]数组
String str="hac";byte[] strBytes = str.getBytes();System.out.println(Arrays.toString(strBytes));
2.调用String的构造器使byte[]数组转换为String对象
String str2=new String(strBytes);
扩容问题:当拼接字符串时(或者使用append添加数据)超过底层数组长度,则需要扩容底层数组,默认情况下数组扩容为原来的两倍,同时将原数组内容复制到新的底层数组中,再进行操作;
效率对比:StringBuilder>StringBuffer>String
序号 | 方法描述 |
---|---|
1 | public StringBuffer append(String s) 将指定的字符串追加到此字符序列。 |
2 | public StringBuffer reverse() 将此字符序列用其反转形式取代。 |
3 | public delete(int start, int end) 移除此序列的子字符串中的字符。 |
4 | public insert(int offset, int i) 将 int 参数的字符串表示形式插入此序列中。 |
5 | replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。 |
序号 | 方法描述 |
---|---|
1 | int capacity() 返回当前容量。 |
2 | char charAt(int index) 返回此序列中指定索引处的 char 值。 |
3 | void ensureCapacity(int minimumCapacity) 确保容量至少等于指定的最小值。 |
4 | void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此序列复制到目标字符数组 dst 。 |
5 | int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引。 |
6 | int indexOf(String str, int fromIndex) 从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。 |
7 | int lastIndexOf(String str) 返回最右边出现的指定子字符串在此字符串中的索引。 |
8 | int lastIndexOf(String str, int fromIndex) 返回 String 对象中子字符串最后出现的位置。 |
9 | int length() 返回长度(字符数)。 |
10 | void setCharAt(int index, char ch) 将给定索引处的字符设置为 ch 。 |
11 | void setLength(int newLength) 设置字符序列的长度。 |
12 | CharSequence subSequence(int start, int end) 返回一个新的字符序列,该字符序列是此序列的子序列。 |
13 | String substring(int start) 返回一个新的 String ,它包含此字符序列当前所包含的字符子序列。 |
14 | String substring(int start, int end) 返回一个新的 String ,它包含此序列当前所包含的字符子序列。 |
15 | String toString() 返回此序列中数据的字符串表示形式。 |
时间戳
System.currentTimeMillis()//返回当前时间与1970.1.1以毫秒为单位的时间差
java.util.Data两个构造器
两个方法
toString():显示当前时间;
getTime():获取时间戳;
java.test.SimpleDateFormat//一个不与语言环境有关的方式来格式化和解析日期的类
格式化:日期转换为文本(字符串)
解析:字符串转换为日期
java.util.Calender 日历类,主要用于完成日期字段之间相互操作的功能;
实例化方式:创建其子类GregorianCalender对象,调用Calender的静态方法getInstance()来实例化;
实例是不可变性的对象,代表yyyy-mm-dd格式的日期;
LocalDate date=LocalDate.now();
表示时间
LocalTime time=LocalTime.now();//hh:mm:ss.xxx
表示日期时间
LocalDateTime datatime=LocalDateTime.now();//yyyy-mm-ddThh:mm:ss.xxx
瞬时类;
方法:
now():获取本初子午线对应的标准时间;
atOffset():添加时间的偏移量;
toEpochMilli():获取与1970.1.1以毫秒为单位的时间差;
格式化:日期转换为字符串;
format();
解析:字符串转换为日期;
parse();
自定义格式化 ofPattern(格式)
1.String类、包装类等已经实现了Comparable接口,重写了comapareTo()方法;
2.对于自定义类,如果需要对象排序,需要实现Comparable接口,然后重写compareTo()方法,在方法体中知名如何排序;
重写规则:当前对象大于比较的对象(方法参数),返回正整数;小于返回负整数;等于返回零;
方法:compare(obj1,obj2)
二者对比
Comparable接口的方法一旦指定,Comparable接口实现类的对象可以在任意地方比较大小;
Comparator接口属于临时比较,临时重写方法;
System类代表系统,系统级别的属性和控制方法放置在该类的内部;
System类的构造器是private的,所以无法创建该类的对象;类内部的方法和成员变量都是static的,可以直接用类来调用;
//类中定义了三个成员变量public final static InputStream in = null;//标准输入流public final static InputStream out = null;//标准输出流public final static InputStream err = null;//标准错误输出流
public static native long currentTimeMillis();//返回当前时间(时间戳)public static void exit(int status) { //退出程序,status为0正常退出;非零异常退出; Runtime.getRuntime().exit(status); }//使用该方法可以在图形界面编程中实现程序的退出功能public static void gc() { //请求垃圾回收 Runtime.getRuntime().gc(); }public static String getProperty(String key) { //将属性名放入形参,返回属性的对应值,比如java.version、java.home、os.name checkKey(key); SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPropertyAccess(key); } return props.getProperty(key); }
Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
java.math.BigInteger 可以表示不可变的任意精度的整数;
BigInteger bigInteger=new BigInteger("666");//根据字符串来创建对象
java.math.BigDecimal 支持不可变的、任意精度的有符号十进制定点数;
类的对象只有有限个并且是确定的,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
如果枚举类中只有一个对象,可以作为一种单例模式的实现;
自定义:
1.私有化构造器(给属性赋值);
2.类的属性用private final修饰;
3.提供当前枚举类的多个对象,用public static final修饰;
4.调用时通过get()方法获得属性;
通过enum关键字定义枚举类,默认继承java.lang.Enum类;
public enum Color { Red,Green,Blue;//直接在类中声明该枚举类的对象,多个对象之间用逗号隔开,末尾以分号结束;}//调用时Color color=Color.Red;
每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。
以上的枚举类 Color 转化在内部类实现:
class Color{ public static final Color RED = new Color(); public static final Color BLUE = new Color(); public static final Color GREEN = new Color();}
Enum的常用方法
values(), ordinal() 和 valueOf() 方法
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
java.util.Scanner 是 JDK5 的新特征,可以通过 Scanner 类来获取用户的输入。
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); String a=scanner.next(); System.out.println("输入的数字是"+a); }public static void main(String[] args) { Scanner scanner=new Scanner(System.in); String a=scanner.nextLine(); System.out.println("输入的是"+a); }
next() 与 nextLine() 区别
next():
nextLine():
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取:
异常发生的原因有很多,通常包含以下几大类:
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-
三种类型的异常:
在一个方法中如果发生异常,这个方法会创建一个异常对象,并转交给JVM,该异常对象包含异常名称、异常描述以及异常发生时应用程序的状态。创建异常对象并转交给JVM的过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈;
JVM会顺着调用栈查看是否有处理异常的代码,如果有,则调用异常处理代码,并将发生的异常传递给它,如果JVM没有找到可以处理该异常的代码,就会将异常转交给默认的异常处理器,默认异常处理器会打印出异常信息并终止应用程序;
所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
Error 用来指示运行时环境发生的错误。
例如,JVM 内存溢出。一般地,程序不会从错误中恢复。
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
Java 语言定义了一些异常类在 java.lang 标准包中。
标准运行时异常类的子类是最常见的异常类。由于 java.lang 包是默认加载到所有的 Java 程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。
序号 | 方法及说明 |
---|---|
1 | public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 |
2 | public Throwable getCause() 返回一个Throwable 对象代表异常原因。 |
3 | public String toString() 使用getMessage()的结果返回类的串级名字。 |
4 | public void printStackTrace() 打印toString()结果和栈层次到System.err,即错误输出流。 |
5 | public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 |
6 | public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 |
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try{ // 程序代码}catch(ExceptionName e1){ //Catch 块}//Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。//一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
throw与throws的区别:throws关键字在方法上声明该方法要抛出的异常,throw在方法内部抛出异常对象;
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
注意下面事项:
class MyException extends Exception{ //只继承Exception 类来创建的异常类是检查性异常类。 }
在Java中定义了两种类型的异常和错误。
Error是程序无法处理的错误,表示运行应用程序中较严重的问题,大多数错误与代码的编写者执行的操作无关,而是表示代码运行时JVM出现的问题;
Error是无法检查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况,比如OutOfMemoryError和StackOverflowError
将一个类定义在类的内部称为内部类;
每个内部类都能独立地继承父类或者实现接口,无论外部类是否已经继承父类或实现接口,对内部类没有影响;
内部类拥有外部类的访问权;
内部类可以定义在一个类里面或者一个方法或作用域里面。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
成员内部类是最普通的内部类,它的定义为位于另一个类的内部;
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:
public class Animal { private int age; private String name; public void shout(){ System.out.println("animal shout"); } class Bird{ //内部类 private int age; private String name; public void shout(){ System.out.println("bird shout"); } }}
public static void main(String[] args) { Animal animal = new Animal();//先创建外部类的对象 Animal.Bird bird=animal.new Bird(); bird.shout();//bird shout}
当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
public void shout(){ System.out.println("animal shout"); new Bird().shout();}
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
注意: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。
匿名内部类也是不能有访问修饰符和 static 修饰符的。
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为 Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,但它不能使用外部类的非static成员变量或者方法,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。
为什么成员内部类可以无条件访问外部类的成员?
编译器会默认为成员内部类添加了一个指向外部类对象的引用,如果没有外部对象,则无法对引用赋初始值,也无法创建内部类对象;
为什么局部内部类和匿名内部类只能访问局部final变量?
解决数据不一致性问题;
1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
3.方便编写事件驱动程序。
4.方便编写线程代码。
1.Java中怎样支持正则表达式?
String类提供正则表达式的方法比如replaceAll()、split()等;Java中可以用Pattern类表示正则表达式对象,里面提供了对正则表达式的操作;
2.int与Integer的区别?
Integer是int的包装类;
3.什么是值传递和引用传递?
值传递:传递该变量的一个副本,不影响原变量;
引用传递:传递对象地址的副本,操作时会改变原对象;
4.==与equals()的区别?
==:基本数据类型比较数据内容,引用类型比较地址值;
equals():一般比较对象的地址,类中若重写equals()方法,则会有其他比较方式如比较对象内容;
5.为什么重写equals()还要重写hashcode()?
在hashmap中,比较key是否相等需要用到这两个方法,先进行hashcode()比较在进行equals()比较,若hashcode不同,则不需要在执行equals()比较;
6.final关键字怎么用?
修饰类时,该类不能被继承,类中成员变量不一定为final,但类中方法隐式默认指定为final方法;
修饰变量时,变量为常量,基本数据类型不能改变,引用类型不能重新指向其他对象;
修饰方法时,方法不能被重写;
7.volatile关键字介绍?
volatile关键字是用来保证有序性和可见性的,作用是保证被其修饰的共享变量对所有线程可见,当一个线程修改后,新的数值可立刻被其他线程得知;volatile并不保证安全性;
8.hashcode()与equals()的联系?
Java中规定,相同的对象有相同的哈希值,哈希值相同的两个对象不一定相同;
9.抽象类与接口的区别?
Abastract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在Abstrct class中必须定义方法体。
abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以通过再次声明其方法为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。
接口中所有方法抽象,实现类必须重写方法;
转载地址:http://prqzi.baihongyu.com/