Java__三个特殊类

一、String类
1.String类的两种实例化方式

    (1)直接赋值

String str = "hello";  //比较常用

    (2)传统方法

String str = new String("hello");  //String本身是一个类,既然是类,它就存在构造方法,
    								 //这就是利用它其中一种构造方法进行赋值
    								 //该构造方法:public String(String str)
2.字符串相等比较
    (1)将基本类型用"=="比较:
    int x=1;
    int y=1;
    System.out.println(x==y);  //true
    (2)将字符串用"=="比较:
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1==str2);  //false

    字符串内容相同,而使用"=="后输出false,利用内存图来分析:


    "=="本身是进行数值比较的,如果用于对象比较,那么所比较的就应该是两个对象所保存的内存地址数值比较,而并没有比       较对象的内容。
    (3)如果想要比较内容,则必须采用String类提供的equals方法。

        String str1 = "hello";
	String str2 = new String("hello");
	System.out.println(str1.equals(str2));  //true

3.字符串常量是String的匿名对象

    (1)在java中,本身没有直接提供字符串常量的概念,所有使用""定义的内容本质上来讲都是String的匿名对象。

	String str1 = "hello" ;  //本质上就是将一个匿名的String类对象设置有名字,而且匿名对象一定保存在堆内存中
	String str2 = new String("hello") ;  
	System.out.println(str1.equals(str2));  //true
	System.out.println("hello".equals(str2));  //true
  (2)任何的字符串常量都是String的匿名对象,所以该对象永远不会为null。
	String str = null;
	System.out.println("Hello".equals(str));  //false

4.String类两种实例化的区别

    (1)直接赋值:

	String str1 = "hello" ;
	String str2 = "hello" ;
	String str3 = "hello" ;
	System.out.println(str1 == str2); // true
	System.out.println(str1 == str3); // true
	System.out.println(str2 == str3); // true

没有开辟新的堆内存空间的原因:String类的设计使用了共享设计模式。在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中已供下次使用(对象池就是一个对象数组,目的是减少开销)。

(2)采用构造方法:

String str = new String("hello");

通过分析可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将会成为垃圾空间。
在String类中提供有方法入池操作public String intern();
如:

	String str1 = new String("hello").intern();
	String str2 = "hello";
	System.out.println(str1==str2);  //true

我们一般会采用直接赋值的方法。
5.字符串常量不可变更

字符串一旦定义不可改变,所有的语言对于字符串的底层实现,都是字符数组,数组的最大缺陷就是长度固定。在定义字符串常量时,它的内容不可改变。

	String str = "hello";
	str = str+"world";
	str += "!!!";
	System.out.println(str);  //hello world!!!

以上字符串的变更是字符串对象的变更而非字符串常量。


可以发现字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。

6.与字符串有关的一些常见方法


7.StringBuffer类

由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer类。在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:

public synchronized StringBuffer append(各种数据类型 b)

如:

	StringBuffer a = new StringBuffer();
	a.append("hello").append(" world");
	System.out.println(a);  //输出:hello world
String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StringBuffer。
注意:String和StringBuffer类不能直接转换。如果想要互相转换,可以采用如下原则:
·String变为StringBuffer:利用StringBuffer的构造方法或append()方法
·StringBuffer变为String:调用toString()方法
除了append()方法外,StringBuffer也有一些String类没有的方法:

(1)字符串反转:

        public synchronized  StringBuffer reverse()

    如:

	StringBuffer a = new StringBuffer("hello world");
	System.out.println(a.reverse());  //输出:dlrow olleh

(2)删除指定范围的数据:

	public synchronized StringBuffer delete(int start,int end)  //区间是左闭右开[)

如:

	StringBuffer a = new StringBuffer("hello world");
	System.out.println(a.delete(5, 10));  //输出:hellod

(3)插入数据:

	public synchronized StringBuffer insert(int offset,各种数据类型 b)

如:

	StringBuffer a = new StringBuffer("hello world");
	System.out.println(a.insert(0,123));  //输出:123hello world
二、Object类
1.简介:Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object进行接收。

如:

	class Person{}
	class Student{}
	public class Test{
		public static void main(String[] args) {
			fun(new Person());
			fun(new Student());
		}
		public static void fun(Object obj){
			System.out.println(obj);
		}
	}  //输出:Person@6d06d69c
	   //	  Student@7852e922

Object类存在的定义好的一些方法:


2.取得对象信息
在使用对象直接输出的时候,默认输出的是一个地址编码。如果现在使用的是String类,该类对象直接输出的是内容,主要原因就是toString()方法的问题。如若觉得默认给出的toString()方法功能不足,就在需要的子类上覆写toString()方法。

如:

	class Person{
		private String name;
		private int age;
		public Person(String name,int age){
			this.age = age;
			this.name = name;
		}
		public String toString(){  //覆写toString()
			return "姓名:"+this.name+" 年龄:"+this.age;
		}
	}
	public class Test{
		public static void main(String[] args) {
			fun(new Person("张三"),10);  //姓名:张三 年龄:10
			fun("hello");  //hello
		}
		public static void fun(Object obj){
			System.out.println(obj.toString());
		}
	}
String作为信息输出的重要数据类型,在Java中所有的数据类型只要遇见了String并且执行了"+",那么都要求将其变为字符串后连接,而所有对象要想变为字符串就默认使用toString()方法。
3.对象比较

String类对象的比较使用的是equals()方法,实际上String类的equals()方法就是覆写的Object类中的equals()方法。

	class Person{
		private String name;
		private int age;
		public Person(String name,int age){
			this.name = name;
			this.age = age;
		}
		public String toString(){  //覆写toString()
			return "姓名:"+this.name+" 年龄:"+this.age;
		}
		public boolean equals(Object obj){  //覆写equals()
			if(obj == null){
				return false;
			}
			if(this == obj){
				return true;
			}
			if(!(obj instanceof Person)){
				return false;
			}
			Person person = (Person) obj;
			return this.name.equals(person.name) && this.age == person.age;
		}
	}
	public class Test{
		public static void main(String[] args) {
			Person per1 = new Person("张三", 10);
			Person per2 = new Person("张三", 10);
			System.out.println(per1.equals(per2));
		}
	}
4.接收引用数据类型
Object可以接收任意的对象,因为Object是所有类的父类,但是Object并不局限于此,它可以接收所有数据类型,包括:类、数组、接口。

(1)使用Object来接收数组对象

	Object obj = new int[]{1,2,3,4,5};  //Object接收数组对象,向上转型
	int[] data = (int[]) obj;  //向下转型,需要强转

(2)使用Object接收接口对象(Object可以接收接口是Java中的强制要求,因为接口本身不能继承任何类)

	interface IMessage{
		public void getMessage();
	}
	class MessageImpl implements IMessage{
		public String toString(){
			return "hello";
		}
		public void getMessage(){
			System.out.println("你好");
		}
	}
	public class Test{
		public static void main(String[] args) {
			IMessage msg = new MessageImpl();  //子类向父类接口转型
			Object obj = msg;  //接口向Object转型
			System.out.println(obj);  //hello
			IMessage temp = (IMessage) obj;  //强制类型转换
			temp.getMessage();  //你好
		}
	}
三、包装类
1.原理:包装类就是将基本数据类型封装到类中。

如:自己定义一个包装类

	class IntDemo{
		private int num;
		public IntDemo(int num){
			this.num = num;
		}
		public int intValue(){
			return this.num;
		}
	}
	//IntDemo实际上就是int数据类型的包装类,利用intValue就可以实现基本数据类型变为对象的需求。
	public class Test{
		public static void main(String[] args) {
			Object obj = new IntDemo(10);  //子类对象向上转型
			IntDemo temp = (IntDemo) obj;  //向下转型
			System.out.println(temp.intValue());  //取出里面的基本数据类型
		}
	}
2.Java为了方便开发,专门提供了包装类的使用,而对于包装类的使用,提供了两种类型。
·对象型(Object的直接子类):Boolean、Character(char);
·数值型(Number的直接子类):Byte、Double、Short、Long、Integer(int)、Float;
3.装箱与拆箱
·装箱:将基本数据类型变为包装类对象,利用每一个包装类提供的构造方法实现装箱处理。
·拆箱:将包装类中包装的基本数据类型取出。

如:手工装箱和拆箱

	Integer num = new Integer(10);  //装箱
	int data = num.intValue();  //拆箱

如:自动装箱与拆箱

	Integer x = 10;  //自定装箱
	System.out.println(x*2);  //可以直接利用包装类对象操作
在这里面依旧存在"=="和"equals"问题;

如:

	Integer num1 = new Integer(10);
	Integer num2 = new Integer(10);
	System.out.println(num1 == num2);  //false
	System.out.println(num1 == new Integer(10));  //false
	System.out.println(num1.equals(new Integer(10)));  //true
说明:对Integer var的赋值在-128~127之间时,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Interger可以直接使用==判断,但是在这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,可以用equals判断。
4.字符串与基本数据类型转换

(1)将字符串变为int型

	String str = "123";
	int num = Integer.parseInt(str);

(2)将字符串变为double

	String str = "123";
	double num = Double.parseDouble(str);
注意:将字符串转为数字的时候,字符串的组成有非数字,那么转换就会出现错误。而字符串与boolean转换就不受此影响。
如果要将基本数据类型转变为字符串:
·任何数据类型使用了"+"连接空白字符串就变为了字符串类型。
·使用String类中提供的valueOf()方法,此方法不产生垃圾。


猜你喜欢

转载自blog.csdn.net/wzh_123_123/article/details/79935516