总结问题解决

来源:互联网 发布:中科大软件学院信息化 编辑:程序博客网 时间:2024/06/05 19:42

2017年8月3日周四第二次总结

1、数组的打印方法问题

数组作为Object的子类,没有对toString()重写,仅仅是做了重载
数组重载的tostring()方法

  • 当数组类型为char的时候

    调用了System.out.print()这个函数,执行的是PrintStream类的函数的 public void println(char x[])方法,代码如下:

      public void println(char x[]) {        synchronized (this) {            print(x);        }    }

可以看到它调用了PrintStream类的print(char s[])方法,代码如下:

     public void print(char s[]) {        write(s);    }

继续调用PrintStream类的write(char buf[])方法,将字符数组的内容显示出来,代码如下:

    private void write(char buf[]) {        try {            synchronized (this) {                ensureOpen();                textOut.write(buf);                textOut.flushBuffer();                charOut.flushBuffer();                if (autoFlush) {                    for (int i = 0; i < buf.length; i++)                        if (buf[i] == '\n')                            out.flush();                }            }        }        catch (InterruptedIOException x) {            Thread.currentThread().interrupt();        }        catch (IOException x) {            trouble = true;        }    }
  • 当数组为其他类型的时候
    调用了System.out.print()这个函数,执行的是PrintStream类的函数的 public void print(Object x)方法,代码如下:
    public void print(Object x) {            String s = String.valueOf(x);            synchronized (this) {                print(s);            }        }

可以看到,此处调用了String类的valueOf(Object obj)方法,而该方法的代码如下:

      public static String valueOf(Object obj) {            return (obj == null) ? "null" : obj.toString();        }

可以看到此方法调用了Object的toString()方法,返回值为

    类名+@+hash值的十六进制表示

2、String为什么定义为final类型

作用就是 final的类不能被继承,不能让别人继承有什么好处? 意义就在于,安全性,如此这般: Java自出生那天起就是“为人民服务”,这也就是为什么Java做不了病毒,也不一定非得是病毒,反正总之就是为了安全,人家Java的开发者目的就是不想让Java干这类危险的事儿,Java并不是操作系统本地语言,换句话说Java必须借助操作系统本身的力量才能做事,JDK中提供的好多核心类比如String,这类的类的内部好多方法的实现都不是Java编程语言本身编写的,好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的,和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的,这不就成了核心病毒了么?
上面所述是最重要的,另外一个方面,上面2位老兄说的也都很对,就是不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了,就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性,如果随便能改了,那么Java编写的程序肯定就很不稳定,你可以保证自己不乱改,但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的,所以这个安全性是很重要的,Java和C++相比,优点之一就包括这一点;
原因绝对不只有这么多,因为如果这些个核心的类都能被随便操作的话,那是很恐怖的,会出现好多好多未知的错误,莫名其妙的错误….
转载自:http://blog.csdn.net/fenglibing/article/details/5486449

3、String/StringBuffer/StringBuilder

String详细讲过,这里就不在赘述,StringBuilder和StringBuffer功能几乎相同,但是StringBuilder是StringBuffer的线程安全版,里面大量的方法需要进行同步,因此效率较StringBuffer低。所以在对线程没要求的场景中推荐使用StringBuffer

StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。

下面详细说一下StringBuffer :
1、StringBuffer对象的初始化

StringBuffer对象的初始化不像String类的初始化一样,Java提供的有特殊的语法,而通常情况下一般使用构造方法进行初始化。

例如:

    StringBuffer s = new StringBuffer();

这样初始化出的StringBuffer对象是一个空的对象。
注意:区别于String

    String str = null; //以此种方式声明的String对象即可进行操作,操作时jvm会自动初始化String对象    StringBuffer result = null; //以此种方式声明的StringBuffer对象,因为没有实例化,不可操作

如果需要创建带有内容的StringBuffer对象,则可以使用:

    StringBuffer s = new StringBuffer(“abc”);

这样初始化出的StringBuffer对象的内容就是字符串”abc”。需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:

    StringBuffer s = “abc”; //赋值类型不匹配    StringBuffer s = (StringBuffer)”abc”; //不存在继承关系,无法进行强转    StringBuffer对象和String对象之间的互转的代码如下:    String s = “abc”;    StringBuffer sb1 = new StringBuffer(“123”);    StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer    String s1 = sb1.toString(); //StringBuffer转换为String

2、StringBuffer的常用方法

StringBuffer类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。

a、append方法

    public StringBuffer append(boolean b)

该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:

    StringBuffer sb = new StringBuffer(“abc”);    sb.append(true);

则对象sb的值将变成”abctrue”。

使用该方法进行字符串的连接,将比String更加节约内容,例如应用于数据库SQL语句的连接,例如:

    StringBuffer sb = new StringBuffer();    String user = “test”;    String pwd = “123”;    sb.append(“select * from userInfo where username=“)    .append(user)    .append(“ and pwd=”)    .append(pwd);

这样对象sb的值就是字符串“select * from userInfo where username=test and pwd=123”。

b、deleteCharAt方法

    public StringBuffer deleteCharAt(int index)

该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:

    StringBuffer sb = new StringBuffer(“Test”);    sb. deleteCharAt(1);

该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。

还存在一个功能类似的delete方法:

    public StringBuffer delete(int start,int end)

该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:

    StringBuffer sb = new StringBuffer(“TestString”);    sb. delete (1,4);

该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。

c、insert方法

    public StringBuffer insert(int offset, boolean b)

该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:

    StringBuffer sb = new StringBuffer(“TestString”);    sb.insert(4,false);

该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。

d、reverse方法

    public StringBuffer reverse()

该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:

    StringBuffer sb = new StringBuffer(“abc”);    sb.reverse();

经过反转以后,对象sb中的内容将变为”cba”。

e、setCharAt方法

    public void setCharAt(int index, char ch)

该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:

    StringBuffer sb = new StringBuffer(“abc”);    sb.setCharAt(1,’D’);

则对象sb的值将变成”aDc”。

f、trimToSize方法

    public void trimToSize()

该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。

总之,在实际使用时,String和StringBuffer各有优势和不足,可以根据具体的使用环境,选择对应的类型进行使用。
此处参考了 http://blog.csdn.net/jason0539

原创粉丝点击