黑马程序员技术交流社区
标题: 关于String类对象级char[]数组输出的不是地址值问题及新型fo... [打印本页]
作者: 黄马良 时间: 2017-12-26 23:26
标题: 关于String类对象级char[]数组输出的不是地址值问题及新型fo...
1.为什么char[]数组和String类型对象直接输出是元素值而不是地址值,地址值又代表了什么含义?
基本数据类型和对象引用
基本数据类型会一直在栈中创建,当声明基本类型时,不需要new。
int a = 10;
栈的读取速度比堆快。基本类型一旦被声明,java将在栈上直接存储它,所以基本类型的变量表示的是数据本身。
假如调用基本类型的包装类来创建对象,那么将会在堆中创建。
Student s = new Student();
等号右侧的new Student() 。这个new是在内存的堆中为对象开辟空间,保存对象的数据和方法。等号左侧 Student s。s指代的是Student的一个对象,称为对象引用,这个对象引用是在栈中创建的。实际上a不是对象本身,它用来指向一个地址。赋值=。这个就是把对象的地址赋给a。此时输出a就是一个内存地址。
那么为什么
String s = new String(“string”)
char[] chs = new char[]{‘a’,’b’,’c’};
这里的s和chs打印输出的不是地址值而是对应的元素本身.
这个地方说明一个问题,假如你自定义的对象重写了.toString方法,此处就会显示你的自定义的重写方法的输出值。
在java的基本类型包装类中就重写了这个方法,所以调用print方法时会自动调用它的toString()方法。
如下程序我先定义了一个Student类和Teacher类分别在测试类中创建对象,并打印
public static void main(String[] args) {
Student s = new Student("张三", 10, 20);
Teacher t = new Teacher("李四", "男");
System.out.println(s);
System.out.println(t);
}
我在Student类中重写了toString()方法,而Teacher类中什么也没做
@Override
public String toString(){
return ("名字是" + name + "----" +"年龄是" + age +"-----" + "分数是" + score );
}
下面可得结果为
名字是张三----年龄是10-----分数是20
com.itheima.Teacher@b03be0
前者仍然是内存地址,后者则是我重写的方法。
print方法在调用事,假如类中的toString()方法没有被重写,则会电泳String.valueof()方法(这个这里暂不讨论),假如重写了就会调用toString方法。
所有的包装类(Integer,Boolean等)都已经重写了toString方法,所以不会输出内存地址,而是输出正确的值。
再来看基本类型的数组输出值
我在这里创建了并初始化了全部基本类型的数组并打印
public static void main(String[] args) {
byte[] a = {1,2,3};
System.out.println(a);
short[] b = {1,2,3};
System.out.println(b);
int[] c = {1,2,3};
System.out.println(c);
long[] d = {1,2,3};
System.out.println(d);
double[] e = {1,2,3};
System.out.println(e);
float[] f = {1.1f,1.2f,1.3f};
System.out.println(f);
boolean[] g = {true,false};
System.out.println(g);
char[] h = {'a','b','c'};
System.out.println(h);
}
下面是输出的结果:
[B@3fa5ac
[S@95cfbe
[I@179dce4
[J@1950198
[D@19bb25a
[F@da6bf4
[Z@1e58cb8
abc
为什么所有类型的数组中只有char的数组类型打印出了正确的结果而没有输出内存地址?
这是因为对于int等其他类型的数组被java认为是一个对象,调用的是下面的方法:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
接着来看valueOf(x)方法:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
然后再进入obj.toString()的源码查看:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
通过这个源码可以看出为什么输出会是[I@179dce4了,I代表的类的名称(其他类型的同理)。
接下来再看char[]调用的源码:
public void println(char x[]) {
synchronized (this) {
print(x);
newLine();
}
}
这里的char x[] 相当于字符数组的初始化即char[] x;
再通过源码查看 print(x)方法:
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
接着再窥探 write(s)里的奥秘:
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
用过查看pintln()方法的源码我们可以知道,由于其他类型的数组都被认为是Object类型了,所以会输出内存地址。而char[]调用的方法是输出char这个数组中的每一个值,所以不是内存地址了。(额具体内部的源码我还看不太懂,但至少可以看出区别)
2.for循环在Java中的应用
通过十几天的基础班的学习,我们学会了for循环的基本使用其基本格式为
for(初始化表达式;条件表达式;循环后的操作表达式) {
循环体;
}
还有一个for的死循环的格式
for(;;){
循环体
}
但其实for循环在java中还有更多的应用
(1)遍历数组的传统方式
数组的遍历
int[] a = {1,2,3,4};
for (int i = 0; i < a.length; i++) {
System.out.println(a);
}
集合专用的迭代器遍历
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
Iterator<String> it = list.iterator();
for(;it.hasNext();){
String s = it.next();
System.out.println(s);
}
(2)而在Java语言的最新版本――J2SE 1.5中,引入了另一种形式的for循环。借助这种形式的for循环,现在可以用一种更简单地方式来进行遍历的工作。
基本格式
for(循环变量类型 循环变量名称 : 要被遍历的对象){
循环体
}
现在数组和集合的遍历可以这样写
集合
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
for(String i : list){
System.out.println(i);
}
数组
int[] a = {1,2,3,4,5};
for(int i : a){
System.out.println(i);
}
由上可知,这里的循环变量类型与要被遍历的对象的元素类型相同,并且循环变量i代表的就是被遍历的对象的元素.
作者: 小浙姐姐 时间: 2017-12-30 16:57
这些内容在后面都是会提到的,第二种循环方法叫“增强for循环”,有利有弊,以后都会学到的哈!你现在在学习中如果遇到这些问题也都可以问你的导师或者助教呢!我们很欢迎你们去挖掘这些,多学习,多思考,都有助于以后的工作呢!加油哦!
作者: 秋子菇凉 时间: 2018-1-7 11:12
不错,知识点很详细
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |