本章内容:
1.基本数据类型的包装类
2.String类,StringBuffer类,StringBuilder类
3.内部类
一.基本数据类型的包装类
1.基本数据类型有时要转成引用数据类型,所以java针对所有的基本数据类型都提供了对应的包装类。但包装类并不是用来取代基本类型的。
下面即对基本数据类型对应的包装类:
基本数据类型 | 包装类 |
byte(字节) | java.lang.Byte |
char(字符) | java.lang.Character |
short(短整型) | java.lang.Short |
int(整型) | java.lang.Integer |
long(长整型) | java.lang.Long |
float(浮点型) | java.lang.Float |
double(双精度) | java.lang.Double |
boolean(布尔) | java.lang.Boolean |
2.包装类和基本数据类型
基本数据类型转换为包装类的语法:
Integer intValue = new Integer(21);
包装类转换为基本数据类型的语法:
Integer integerId=new Integer(25);
int intId=integerId.intValue();
3.自动装箱、拆箱
JDK5.0中为基本数据类型提供了自动装箱(boxing)、拆箱(unboxing)功能:
装箱:将基本数据类型包装为对应的包装类对象
下面就char型来诠释自动装箱拆箱
package boxing;
public class CharacterDemo {
public static void main(String[] args) {
Character c='a'; // 自动装箱
char x=c; // 自动拆箱
System.out.println("变为大写:"+Character.toUpperCase('a'));
System.out.println("变为小写:"+Character.toLowerCase('Y'));
}
}
运行截图如下:
package boxing;
public class IntegerDemo {
public static void main(String[] args) {
System.out.println("int的最大值:"+Integer.MAX_VALUE);
System.out.println("int的最小值:"+Integer.MIN_VALUE);
Integer a=100; // 自动装箱
int b=a; // 自动拆箱
String str="123";
int temp=Integer.parseInt(str); // 将字符串转换为int
System.out.println(temp+5);
}
}
运行结果截图如下:
二.字符串相关类
1.String类
* String代表字符串类型,字符串内容本身不可改变,字符串存储于“字符串常量池“中。
补充:栈内存一般放局部变量的基本数据类型。对象的引用类型。
静态区放静态,对所有实例化对象共享。
字符串常量值其实也放在堆内存中,但单独拿出来讲就在字符串常量池里,常量池属于堆内存。
* String的两种实例化方式:
a.直接赋值法(常用)
eg: String str=“Hello”;
b.通过new操作符实例化
eg:String str=new String(“hello”);
* 一个字符串就是一个String类的匿名对象。所谓匿名对象,就是在堆内存中开辟了空间,但在栈内存中并没有引用指向的对象。
例如:
package string.trap;
public class StringDemo {
public static void main(String[] args) {
String str="hello";
change(str);
System.out.println(str);
}
public static void change(String str){
str="中国";
}
}
在此时change里的方法的字符串并没有被指向,这个部分是在堆内存中另开辟的空间,但在栈内存中没有引用指向对象,故输出结果依然是“hello”。
运行结果截图为:
* 字符串常用方法:
1.public String(byte[] bytes)
使用平台的默认字符集解码,将字节数组转换为字符串
2.public String(byte[] bytes,Charset charset)
使用指定字符集解码,将字节数组转换为字符串
3.public char charAt(int index)
根据索引位置获取字符串中的某个字符
4.public boolean contains(CharSequence s)
判断当前对象代表的字符串是否包含参数字符串内容
5.public boolean equals(Object anObject)
判断字符串内容是否相同
6.public byte[] getBytes()
将字符串转换为字节数组
7.public int indexOf(String str)
返回参数字符串在当前字符串中的索引位置
8.public int lastIndexOf(String str)
从后往前找参数字符串,返回参数字符串在当前字符串中的索引位置
9.public int length()
返回当前字符串的长度
10.public String toLowerCase()
将字符串转换为小写
对以上常用方法进行验证:
package string;
public class StringMethod {
public static void main(String[] args) {
String str="中华人民共和国";
System.out.println(str.charAt(2)); // 根据索引位置获取字符串中的某个字符
System.out.println(str.contains("人民")); // 判断当前对象代表的字符串是否包含参数字符串内容
System.out.println(str.indexOf("民共和"));
// 将"abcde"的d变为大写
String s1="abcdedx";
System.out.println("从后往前找d:"+s1.lastIndexOf("d"));
String s2="wxYz";
System.out.println(s2.toUpperCase());
System.out.println(s2.toLowerCase());
System.out.println("中华人民共和国".substring(3));
System.out.println("中华人民共和国".substring(3,6));
String s3=" 中 国 人 ";
System.out.println("s3的长度:"+s3.length());
System.out.println("删除了前后空格后的长度:"+s3.trim().length());
System.out.println("*************************************");
String country="中国,美国,俄罗斯,意大利,瑞典";
String[] array=country.split(",");
System.out.println("遍历拆分后的字符串:");
for(String cou:array){
System.out.print(cou+" ");
}
}
}
实验结果截图:
2.StringBuffer类,StringBuilder类
这两个类功能几乎一样,代表可变的字符序列,称为字符串缓冲区,工作原理是:预先申请一块内存,存放字符序列,如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。
StringBuffer,StringBuilder,String的区别:
StringBuffer和StringBuilder是可变对象,若连续操作String对象则会产生大量垃圾,而且“断开------连接”很频繁。
StringBuffer与StringBuilder相比,StringBuilder是线程不安全的。
就StringBuffer举例:
package stringbuffer;
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer();
sb.append("中国").append("香水").append("Java");
System.out.println("反转之前:");
System.out.println(sb.toString());
sb.reverse(); // 反转缓冲区的内容
System.out.println("反转之后:");
System.out.println(sb.toString());
StringBuffer sb2=new StringBuffer();
sb2.append(false).append(12.5).append("hello");
sb2.insert(1,true); // 在索引为1处插入true
System.out.println(sb2);
}
}
运行结果截图:
三.内部类
1.在类的内部定义另一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而Outer则称为外部类。
2.内部类的定义格式
public class 外部类{
//外部类成员
public class 内部类{
//内部类成员
}
}
3.内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
** 什么时候使用内部类?
类中有属性或者方法不足以描述某个复杂的问题,但这个问题又包含在类中,这时就应该使用内部类。
使用内部类的好处:
1 可以方便地访问外部类的私有属性
2 减少了类文件编译后的产生的字节码文件的大小
缺点:使程序结构不清楚
**** 成员内部类
成员内部类中不能定义static变量
成员内部类持有外部类的引用
外部类.内部类 内部类对象=外部类实例.new 内部类();
如:
package inner.member;
public class Outer {
private String name="中国人";
// 成员内部类
class MemberInner{
public void method(){
System.out.println("内部类可以访问外部类的私有属性:"+name);
}
}
public MemberInner getMemberInstance(){
return new MemberInner();
}
}
package inner.member;
public class TestMember {
public static void main(String[] args) {
Outer out=new Outer();
out.getMemberInstance().method(); // 通过在外部类中的成员方法中获取内部类对象
// 外部类.内部类 内部类对象=外部类实例.new 内部类();
Outer.MemberInner in=out.new MemberInner();
in.method();
}
}
截图如下:
**** 静态内部类
如果一个内部类使用static声明,则此内部类就称为静态内部类,其实也相当于外部类。可以通过外部类.内部类来访问。
静态内部类不会持有外部类的引用,创建时可以不用创建外部类对象
静态内部类可以访问外部的静态变量,如果访问外部类的非static成员变量必须通过外部类的实例访问
外部实例化静态内部类对象的格式:
外部类.内部类 内部类对象= new 外部类.内部类();
如:
package inner.staticdemo;
public class Outer {
private String name="中国";
private static int population=14;
static class StaticInner{
public void method(){
System.out.println("静态内部类直接访问外部类的static属性:"+population);
Outer out=new Outer();
System.out.println("在静态内部类中通过外部类对象访问非static属性:"+out.name);
}
}
public static StaticInner getStaticInner(){
return new StaticInner();
}
}
package inner.staticdemo;
public class TestStaticInner {
public static void main(String[] args) {
Outer.getStaticInner().method();
System.out.println("************************");
Outer.StaticInner in=new Outer.StaticInner();
in.method();
}
}
截图如下:
*** 局部内部类
局域内部类是定义在一个方法中的内嵌类,所以类的作用范围仅限于该方法中,而类生成的对象也只能在该方法中使用。
局域内部类不能包含静态成员
特别注意:局域内部类要想访问包含其的方法中的参数,则方法中的参数前必须加上final关键字(JDK<=1.7)。
如:
package inner.local;
public class Outer {
private String name="中国";
public void func(int x){
class LocalInner{
public void method(){
System.out.println("局域内部类访问外部类的属性:"+name);
System.out.println("局域内部类访问包含其方法的参数"+x);
}
}
new LocalInner().method(); // 在局域内部类所在的方法中实例化局域内部类对象,并调用其方法
}
}
package inner.local;
public class TestLocal {
public static void main(String[] args) {
Outer out=new Outer();
out.func(5);
}
}
截图如下:
*** 匿名内部类
如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类
没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内
部类就比较合适。
如:
package inner.anonymity;
public interface Jumping {
public void jump();
}
package inner.anonymity;
public class TestAnonumity {
public static void main(String[] args) {
Jumping j=new Jumping(){
@Override
public void jump() {
System.out.println("某人跳楼了...");
}
};
j.jump();
}
}
结果截图: