关于Java的String类的一些疑惑以及解答

来源:互联网 发布:陈震媳妇 淘宝店叫什么 编辑:程序博客网 时间:2024/05/21 09:04

我初学java,对于java很多知识还是一知半解。前一阵子,我写了一个简单的类,暴露了几个我还没掌握的知识点。在此发表一下。

对于这些问题,我也在CSDN发过一个帖子,结合回帖以及到别处查询,最终解决了。

点击打开帖子

我写了一个Student类,里面包含一个searchContact的方法,就是在通讯录里面查找某个人。代码我就贴出来,大家关注一下searchContact这个方法以及main函数。

import java.util.Scanner;  class Student{    private String name;    private int age;    private String gender;    private String phone;    private String address;    private String email;    public Student[] Contact;         public Student()    {        name=null;        age=0;        gender=null;        phone=null;        address=null;        email=null;        Contact=new Student[100];    }         public Student(String strName, String strGender)    {        name=strName;        gender=strGender;        age=0;        phone=null;        address=null;        email=null;        Contact=new Student[100];    }         public String toString()    {        String ObjectToStr;        ObjectToStr="Name    |    "+name+"\r\n"                    +"Age    |    "+age+"\r\n"                    +"Gender    |    "+gender+"\r\n"                    +"Email     |    "+email+"\r\n"                    +"Addr      |    "+address;        return ObjectToStr;    }         public void Eat(String food)    {        System.out.println(name+" is eatting "+food);    }         public void Drink(String drink)    {        System.out.println(name+" is drinking "+drink);    }         public void Play(String what)    {        System.out.println(name+" is playing "+what);    }         public void Sleep()    {        System.out.println(name+" is sleeping ");    }         //    public void setName(String strName)    {        name=strName;    }    public String getName()    {        return name;    }         //    public void setAge(int intAge)    {        age=intAge;    }    public int getAge()    {        return age;    }         //    public void setGender(String strGender)    {        name=strGender;    }    public String getGender()    {        return gender;    }         //    public void setPhone(String strPhone)    {        name=strPhone;    }    public String getPhone()    {        return phone;    }         //    public void setAddress(String strAddress)    {        address=strAddress;    }    public String getAddress()    {        return address;    }         //    public void setEmail(String strEmail)    {        email=strEmail;    }    public String getEmail()    {        return email;    }         public static Student SearchContact(Student st, String searchCondition)    {        Student someone=new Student();        for (Student s : st.Contact)        {            if(s!=null&&(s.name==searchCondition||s.email==searchCondition||s.address==searchCondition))            {                someone=s;                break;            }                     }        return someone;    }         public static void main(String[] args)    {        Student s1=new Student("Marcus","Male");        s1.setAge(23);        s1.setAddress("Dongguan");        s1.setEmail("abc@hotmail.com");        s1.Eat("Apple");        Student John=new Student("John","Male");        Student Marry=new Student("Marry","Female");        s1.Contact[0]=John;        s1.Contact[1]=Marry;        String searchText;//="John";        Scanner sc=new Scanner(System.in);        while(sc.hasNext())        {        String searchText1=sc.nextLine();  // I input a string "Marry"        searchText="Marry"; // a variable has value "Marry"        System.out.println("value from keyboard equals the value from hardcode ? : "+searchText1.equals(searchText));//compare them, and it will return true        Student ss=SearchContact(s1,searchText1); // but it's strange, I pass searchText, and the function returns the true result, while I pass serachText1                                                  //it returns the wrong result.        Student sss=SearchContact(s1,searchText);        System.out.println("value from keyboard:\r\n"+ss);        System.out.println("value from hardcode:\r\n"+sss);        //if(ss.name==null)System.out.println("No <"+searchText+"> can be found in "+s1.name+"'s contact book");        //else System.out.println(ss.toString());        }             }}

main函数的代码有些冗余代码,那是我测试用的。

我当时提出的问题,就是为什么我键盘输入的Marry和在代码里hardcode的Marry,分别赋值给一个变量,传到searchContact函数里面,得到不一样的结果。

这个类有两个比较大的问题。第一,searchContact函数里面的比较逻辑,最好不要用“==”比较,因为==比较的是对象地址(或比较对象),虽然表面上两个字符串的value是一样的,但可能是两个不同的对象,基于这个函数的设计目的,这里应该比较的是value,所以用equals比较好一点。于是我改成了equals。结果正确了。本来以为问题解答了,但想了想,还是有问题,在searchContact函数未修改前,为什么在代码里面用字符串常量赋值给一个变量再传给函数或者直接使用字符串常量传给函数返回的结果是正确的,而用键盘输入一个等值的字符串赋值给一个变量再传给函数,而得到的结果就会不一样呢?第二点,上面的问题就涉及到java对string对象的存储问题。函数里面的变量赋值是用String str=value的方式,而刚好类中的构造函数给成员变量name赋值也是这种赋值方式。采用str=value这种方式的赋值,最多创建一个string对象,若果常量池中不存在Marry这个字符串,就创建一个string对象,值就是Marry;如果常量池中存在Marry这个对象,当采用str=value的方式赋值时,仅仅把Marry这个对象的引用赋值给str,而不是建立新的对象。因此,所有采用这种方式赋值的字符串变量,如果具有相同的value,那么,它们是相等的。而另一种赋值方式是String str2=new String(value),这种方式是最少建立一个对象,就是每次用这种方式都新建一个对象。所以,无论value是否相等,两者比较都不相等。而main函数中的nextLine()和next()这个函数的返回值相当于返回new String(value),所以是另外一个对象,因此调用searchContact方法返回的结果永远都会是false。参考帖子

这是我修改后的部分代码:(测试通过)

public Student SearchContact(String searchCondition){Student someone=new Student();for (Student s : Contact){if(s!=null&&(searchCondition.equals(s.name)||searchCondition.equals(s.email)||searchCondition.equals(s.address))){someone=s;break;}}return someone;}

public static void main(String[] args){Student s1=new Student("Marcus","Male");s1.setAge(23);s1.setAddress("Dongguan");s1.setEmail("abc@hotmail.com");Student John=new Student("John","Male");Student Marry=new Student("Marry","Female");s1.Contact[0]=John;s1.Contact[1]=Marry;String searchText;//="John";Scanner sc=new Scanner(System.in);while(sc.hasNext()){String searchText1=sc.nextLine();Student stuSearched=s1.SearchContact(searchText1); if(stuSearched.name==null)System.out.println("No <"+searchText1+"> can be found in "+s1.name+"'s contact book");else System.out.println(stuSearched.toString());}}


0 0
原创粉丝点击