【String类的API引发的思考】

握草 2017-12-09 08:09:53
很简单但是很值得花时间想一想的问题,请看:

String s="abc";
s. toUpperCase();
//output: ABC

这里直接对对象进行操作,但是问题是这里toUpperCase根本没有方法传参!!,这就表明没有相应的返回供外界使用。当然了,这里本来str点toUpperCase也不需要返回值直接操作对像,但是既然没有对toUpperCase( )方法传参数,也就表明当方法结束后,toUpperCase( )方法「弹栈」,销毁内存占用,那么计算机究竟是「怎么样让这里的对象引用(实际是操作对象)的内容(地址)改变的(小写变大写)呢」??
===================================
BTW,我认为是不是可以这样写:
String. toUpperCase(s);

前提要是String类的toUpperCase( )方法为静态,这样既然从方法外界有输入,那么只要就有「对应的(你别说局部变量搞个值然后return那个值这不叫对应的)」的值,这时候只要在让一个变量接受return的相应值就好了:
String ss=String. toUpperCase(s);

这时候我们就不看原先的s了,因为有关大写的属性已经被保存到了ss里面
======================================
可是
s. toUppercase( )

这算什么?没有相应的返回值啊??
...全文
291 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
迟到_啦 2017-12-19
  • 打赏
  • 举报
回复
引用 8 楼 qq_40778536 的回复:
但是你看源码,到底还是传递了参数。如果不传递参数在方法内就无法拿到方法外面的信息
对外界来说没有传参,只是对象调用了无参函数,函数内部还有方法获取了对象的属性,相当于拿到了参数,但是外界是不需要手动传参,不需要关心这个事。 有参函数就是通过对象获取不到该参数,必须通过形参传入函数才能进行进一步下一步处理,同样也是对象调用,但是对象里没有参数值。 所以对外界来说,有参就是必须手动传入形参;无参就是无需关心参数,直接调用方法。 对于内部来说,只要处理参数的方法都必须先拿到参数才能处理,只不过拿到的方法有所不同。
迟到_啦 2017-12-19
  • 打赏
  • 举报
回复
引用 9 楼 qq_40778536 的回复:
还有源码里面,那个我不明白怎么就可以实现了[a-z]到[A-Z]的一一映射呢? 我的第一反应是建立了一个内置的Map接口,通过键值对@迟到_啦
我以前也没注意,又看了一下里面相关方法源码,用到了的Map集合的hashTable实现类,和hashMap类似,只是它是线程安全的,还用到了Set集合的hashSet实现类,具体怎么实现转变的我也只是看了个大概,不能拿出来班门弄斧,你有兴趣可以自己在研究研究源码
握草 2017-12-18
  • 打赏
  • 举报
回复
还有源码里面,那个我不明白怎么就可以实现了[a-z]到[A-Z]的一一映射呢? 我的第一反应是建立了一个内置的Map接口,通过键值对@迟到_啦
握草 2017-12-18
  • 打赏
  • 举报
回复
但是你看源码,到底还是传递了参数。如果不传递参数在方法内就无法拿到方法外面的信息
迟到_啦 2017-12-12
  • 打赏
  • 举报
回复
toUpperCase()源码


toUpperCase(Locale locale)源码

public String toUpperCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
}

int firstLower;
final int len = value.length;

scan: {
for (firstLower = 0 ; firstLower < len; ) {
int c = (int)value[firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE)
&& (c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR)
|| (c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
}

char[] result = new char[len]; /* may grow */
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */

/* Just copy the first few upperCase characters. */
System.arraycopy(value, 0, result, 0, firstLower);

String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] upperCharArray;
int upperChar;
int srcChar;
int srcCount;
for (int i = firstLower; i < len; i += srcCount) {
srcChar = (int)value[i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent) {
upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
} else {
upperChar = Character.toUpperCaseEx(srcChar);
}
if ((upperChar == Character.ERROR)
|| (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (upperChar == Character.ERROR) {
if (localeDependent) {
upperCharArray =
ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
} else {
upperCharArray = Character.toUpperCaseCharArray(srcChar);
}
} else if (srcCount == 2) {
resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
continue;
} else {
upperCharArray = Character.toChars(upperChar);
}

/* Grow result if needed */
int mapLen = upperCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0, i + resultOffset);
result = result2;
}
for (int x = 0; x < mapLen; ++x) {
result[i + resultOffset + x] = upperCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i + resultOffset] = (char)upperChar;
}
}
return new String(result, 0, len + resultOffset);
}

简单看一下可以明白该方法可以拿到s的值,并且把s的每一个字符都转换为大写,那么里面的参数有什么用呢?

就是为了可以正常转换大小写,
 if (locale == null) {
throw new NullPointerException();
}

这句代码可以没有该参数会报异常,也就得不到转换后的新字符串。

toUpperCase(Locale locale)方法解释


Locale.getDefault()方法解释


针对此题总结:
s.toUpperCase()之后得到了转换为大写的字符串,因为toUpperCase()内部拿到了s的值,并且把它按照相应的语言环境转换为了大写的字符串,最后作为返回值返回,所以String ss = s.toUpperCase()之后ss就拿到了转换之后的值。

还有不理解欢迎骚扰
迟到_啦 2017-12-12
  • 打赏
  • 举报
回复
上面写错了一个 地方,应该是getName()方法
迟到_啦 2017-12-12
  • 打赏
  • 举报
回复
我给你举个类似的你应该用过的例子:

假如现在有一个student对象,有一个setName()方法,那么我在main函数中怎么来实现拿一个学到的名字呢?怎么拿到一个处理过的名字呢?


1.Student stu = new Student()创建一个sutdent对象
2.然后String name = stu.getName();这就拿到了一个学生的名字,这很好理解(就是getName()方法返回了Student类的name属性,那么你只要创建一个学生stu,我就可以通过这个对象引用拿到该对象名字)
3.如何获取处理过的名字呢?(比如:有一个要求是拿到“我的name”,而不是仅仅返回对象名字,也就是getName把名字拼接一个字符串“我的”再返回---return "我的"+this.name)
那这样获取的字符串不就是要求的么。


总结: 通过一个函数改变一个对象的属性或者说获取一个对象的某属性改变后的新属性并不是说一定要传参,因为创建的对象引用已经包括了这个对象的所有属性(也就是说内部可以拿到值去处理,不需要手动传参),可以直接拿到它的属性值,然后如果想要处理该值再进一步处理(该题是要将String对象值变为大写),最后将处理之后的值作为返回值,用新引用去接受也就拿到了目标值。

toUpperCase()方法源码分析

楼下见:

miaoch 2017-12-11
  • 打赏
  • 举报
回复
引用 2 楼 qq_40778536 的回复:
但是你没有传参数给toUpperCase方法,怎么返回呢??
第一次听说不给方法传参数,方法就不能返回。 举个最简单的例子吧,集合用过吧? list.size() 不也是不传参数也能返回list的长度吗。 怎么感觉你这个问题问的那么奇怪呢。 另外看看源码就可以知道:

public String toUpperCase() {
    return toUpperCase(Locale.getDefault());//具体怎么实现在去看源码
}
明明就是有返回值的呀。而且经验也告诉我,String s = "abc".toUpperCase(); //s:"ABC"
  • 打赏
  • 举报
回复
方法的定义是啥, 访问控制 返回值 方法名。肯定有返回嘛,只不过可能是void。再有参数和返回有什么关系呢?
握草 2017-12-09
  • 打赏
  • 举报
回复
但是你没有传参数给toUpperCase方法,怎么返回呢??
天之上有什么 2017-12-09
  • 打赏
  • 举报
回复
toUpperCase方法的返回值是调用对象的大写格式字符串,无参数代表使用本地默认规则,写参数也可以,不过要按它的规则写

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧