由于网络上传内容大小有限制的原因,我不得不把大段的博客分开成几部分来写。
重点四:匿名对象
匿名对象,顾名思义就是没有给出名字的对象,一般匿名对象只是用一次,只在堆空间内开辟内存,不在栈空间内开辟内存指向堆空间内存的内容。
匿名对象的使用方式:
new 类名(参数列表).方法
类的设计总结:
下面对前面介绍的类的设计进行总结。
1、类包括两大部分:属性和方法,其中方法包含普通方法和构造方法,构造方法有系统默认的和重载后的构造方法两种。
2、类的全部属性必须用private封装起来,通过setter和getter方法访问或者通过重载构造方法访问。
3、对象作为方法参数传递时,只需要写上对象名就可以了。
重点五:String类的设计与使用
在前面介绍基本数据类型时候已经介绍过一种数据类型char,这种数据类型占内存2个字节,也就是说相当于2个英语字符或者一个汉字,显然这个对于实际应用包含很多个字符的单词或者短语是很难满足的。所以需要一种新的数据类型,这种数据类型就是字符串。字符串从形式上看和数组是很类似的,其实处理方式确实是类似的。实例化一个String类时,在堆内存存放内容,在栈内存存放指向堆内存的地址。
实例化方式:
1、String str = null;
str = new String(“字符串”);
2、String str = “字符串”;
3、String str = new String(“字符串”)
这三种方式在java处理中1和3是一样的,2和3/1是有区别的。注意:这两种处理方式和基本数据类型形式上是一样的,比如定义一个int 数据也有两种:
1、int a = null;a = 3;
2、int a = 3;
但基本数据类型的定义和引用数据类型的本质是不一样的。通过下面两种等值方法比较可以看出String两种实例化方式的不同:
1、==方式比较的是地址和内容
class Demo01{
public static void main(String[] args){
String str1 = “renshisan”;
String str2 = new String(“renshisan”);
String str3 = str2;
System.out.println(“str1 == str2:” + (str1 == str2));
System.out.println(“str1 == str3:” + (str1 == str3));
System.out.println(“str2 == str3:” + (str2 == str3));
}
}
上述执行结果是false,false,true。1和2 是因为其执行内容所在的堆内存地址不同,2和3相同是因为2赋值给3,将其指向内容的使用权共享给了3,所以地址相同,因而对象相同。
2、equals方式比较的是内容
class Demo01{
public static void main(String[] args){
String str1 = “renshisan”;
String str2 = new String(“renshisan”);
String str3 = str1;
System.out.println(“str1 equals str2:” + (str1.equals(str2));
System.out.println(“str1 equals str3:” + (str1.equals(str3));
System.out.println(“str2 equals str3:” + (str2.equals(str3));
}
}
执行结果是三个均为true
上述出现三个不同的原因是两种实例化不同的原因。那么哪一种实例化更好呢?先看一个实例:
class Demo02{
public static void main(String[] args){
System.out.println(“\”Hello\” equals \”Hello\”:” + (“Hello”.equals(“Hello”))
}
}
执行结果是:Hello equals Hello:true
上述执行结果说明一个字符串可以调用String类方法,一个字符串是一个匿名对象。
用String str1 = “renshisan”;这种方式定义一个String类,在java中是这样处理的,如果一个字符串已经被一个名称所引用,以后再有相同字符串声明时,不再开辟堆内存空间,而是把字符串使用权共享,这种设计方式被称为对象池的共享设计。
字符串内容不可改变
字符串一旦被定义后将不可改变!这一点必须要牢记。
例如:
class Demo03{
public static void main(String[] args){
String str = “hello”;
str = str + “world!”;
System.out.println(“str:” + str);
}
};
输出结果是:str:hello world!
看起str是改变了,但实际上是没有改变的。
栈内存 堆内存
str ———— hello
world!
hello world!
最后的结果是str断开与hello连接即断开指向hello,转而指向hello world!的堆内存地址。所以str一开始声明指向的str是没有改变的。这种断开连接机制在使用时候需要注意,在循环中,如果用上述方式来连接字符串,代码性能是很低的,后面介绍StringBuffer来解决这个问题。
String类常用方法
由于上传限制的原因只能截取一部分了。
介绍常用的使用方法:
1、将字符串变成字符数组的方法
可以使用toCharArray()将字符串变成一个数组,或使用String类构造方法来实现这一点
package Chapter5Excercise;
//本类展示字符串与字符数组的互转
class ClassDemo04 {
public static void main(String[] args){
String str1 = "renshisan";
char c[] = str1.toCharArray();
for(int i = 0;i
//用一个循环
System.out.print(c[i]+"\t");
}
System.out.println(" ");
String str2 = new String(c);//构造方法来将字符数组转成字符串,全部的
String str3 = new String(c,0,3);//构造方法将字符数组的第0至第3个变成字符串
System.out.println(str2);//对象名称直接作为参数传递
System.out.println(str3);
}
}
2、从字符串中取出指定位置的字符
这里使用的方法是charAt(位置数值)
如:str = “hello”;str.charAt(3);结果输出的是第三个字符l,第0个是h
3、将一个字符串变成byte字符数组,也可以把一个byte字符数组变成一个字符串
将字符串变成字符数组使用方法getBytes()
将byte字符数组变成字符串使用构造方法,使用方式通字符数组
package Chapter5Excercise;
class ClassDemo05 {
public static void main(String[] args){
String str = "renshisan";
byte b[] = str.getBytes();
System.out.println(new String(b));
System.out.println(new String(b,0,3));
}
}
4、取得一个字符串的长度
方法:length();
使用方式:对象名.length()
注意:length与length()是两种不同的方法,length是用于数组的取长度方法,length()是一个String类的一个方法。
5、查找一个指定字符存在位置,如果不存在返回-1
方法:indexOf()
使用方式str.indexOf("c",3)从第4个位置开始查找c
6、去掉字符串左右空格
方法:trim()
7、字符串截取
方法substring() 注意:单词全部小写了
8、按照指定的方式拆分字符串
方法:split()
注意:1、拆分后以字符串数组方式返回,直接输出对象方式将会报错
2、split携带的拆分参数标志将不会在被拆分的结果中输出,如renshisan,以n为拆分标志,拆分后的结果就是re shisa
9、将字符串转成大写或者小写
转成大写:toUpperCase()
转成小写:toLowwerCase()
10、判断是否以指定的字符串开头或者结尾
方法:startWith()
11、不区分大小写进行内容比较
方法:equalsIgnoreCase()
使用方式str1.equalsIgnoreCase(str2)
12、将指定字符串用别的字符串来代替
方法:replaceAll(“abc”,“cd”)
对象的引用:注意对象的引用本质是堆内存使用权的共享,对于String类来说是个特别的,其内容不可改变,千万记住。
举个栗子:
package Chapter5Excercise;
class ClassDemo08 {
int temp = 30 ;
};
class ClassDemo06{
public static void main(String[] args){
ClassDemo08 demo = new ClassDemo08();//实例化,但没有初始化值,那么对象的指向会是的初始化值
System.out.println("引用传递前的结果:" + demo.temp);
fun(demo);
System.out.print("引用传递后的结果:" + demo.temp);
}
public static void fun(ClassDemo08 demo){
demo.temp = 59;
}
};
执行结果是:
引用传递前的结果:30
引用传递后的结果:59
重点六:this、static关键字介绍
本部分介绍this和static两个关键字。
介绍this关键字:
this与super这两个关键字在java中与本类和父类有关。Super关键字在后面介绍,先介绍this关键字。
this关键字在java中有三种用法:
1、表示类中的属性
2、表示调用本类的构造方法
3、表示当前对象
详细介绍如下:
1、 this表示类中的属性
使用方式:this.类属性
解释:先看一段代码:
package Chapter5Excercise;
class Person01 {
public static void main(String[] args){
private String name;
private int age;
public Person01 (String n,int a){
name = n;
age = a;
}
public String getInfo(){
return "姓名:" + name + " 年龄:" + age;
}
}
}
在这段代码中,我们看到构造方法Person01的形式参数n,a只是随意的字符,看不出代表什么意思,这样对代码理解是很麻烦的。可以修改成与实际参数一致,方便理解。
public static void main(String[] args){
private String name;
private int age;
public Person01 (String name,int age){
name = name;
age = age;
}
public String getInfo(){
return "姓名:" + name + " 年龄:" + age;
}
}
}
这样修改后还是有问题的:
name = name;
age = age;
会导致系统无法分清参数,可以实例化后执行,发现最后取得的name为null,age为0
这时候再修改一下,使用this关键字:
this.name = name;
this.age = age;
用this关键字表示的含义是:将调入函数的实际参数值,赋给类的属性,这样就不会报错了。
2、使用this(),调用构造方法
this 关键字调用构造方法只能放在this所在的构造方法的代码块首行。
例如
package Chapter5Excercise;
class Person {
private String name;
private int age;
public Person(){//无参构造
System.out.println("一个新的Person对象被实例化");
}
public Person(String name,int age){
this();
this.name = name;
this.age = age;
}
public String getInfo(){
return "姓名:" + name + " 年龄:" + age;
}
};
class ClassDemo09{
public static void main(String[] args){
Person per = new Person("任磊",25);
System.out.println(per.getInfo());
}
};
3、 this表示当前对象
看一个对象比较的例子,这种用法很常见,需要重点认识:
package Chapter5Excercise;
class Person009{
//属性区
private String name;
private int age;
//提供实例化的构造方法区
public Person009(String name,int age){
this.setName(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//提供比较的功能
public boolean compare(Person009 per22){
Person009 per1 = this;
Person009 per2 = per22;
//判断地址是否相等
if(per1 == per2){
return true;
}
if((per1.name.equals(per2.name))&&(per1.age==(per2.age))){//equals用于字符串比较,不能用于整型值
return true;
}else {
return false;
}
}
};
public class ThisDemo07 {
public static void main(String[] args){
//实例化两个对象
Person009 per1 = new Person009("任磊",25);
Person009 per2 = new Person009("任磊",25);
//传递参数用于比较
if(per1.compare(per2)){
System.out.println("两个对象相等");
}else{
System.out.println("两个对象不相等");
}
}
};
2、static关键字介绍
static意思是静态的或全局的,顾名思义,被这个修饰词修饰的变量用于共享给对象使用的。静态的不代表不可以改变,意思是全局的,就是大家都可以使用。
static属性的修改由类来进行修改,使用语法:
类名称.static属性名 = 值;
附:java常用内存区
1、栈内存空间:保存所有的对象引用的堆内存地址
2、堆内存空间:保存每个对象属性的具体内容
3、全局数据区:保存static类型属性
4、全局代码区:保存所有方法的定义
理解main方法:
主函数的整体结构是:
public static void main(String[] args){
}
public:表明该方法可以被外部调用
static:全局方法,此方法可由类名称来直接调用
void:主方法是程序的起点,不需要方法任何值
main:系统默认的方法名,执行时候,系统找到该方法名,然后开始执行
strings args[]:表示运行时的参数。参数的传递形式是java类名称 参数1,参数2。。
如果一个方法被主方法调用,必须写成如下形式:
Public static 返回值类型 方法名称 参数列表{}
用public修饰的原因是这个方法要被主方法main调用
用static修饰的原因是主方法是static静态的,静态方法不能调用非静态方法。
仍然用过程的方式来分析问题,但是过程每一个函数代表一种行为,将行为对应成一个类就变成了面向对像分析的方式。