java十宗罪

zhouyou96 2011-06-17 03:16:47
加精
java十宗罪


好吧,我知道看这标题很多人就忍不住要拍砖或表示不赞同了,我都接受。

我在遇到问题时,找一些搞java朋友求助,有能解决的,我想说的是不能解决的情况下,他们大多会说:“你怎么能这么弄呢?这么搞是不行的,你首先在思路上就错误了,我们从来就不这么做。”,比如“我们一般很少用存储过程,你用这么多存储过程,我建议你使用hibernate代码实现你的业务,而不是用存储过程”,这个问题是在我遇到用hibernate调存储过程时发生一些状况后,我一个搞java的朋友也无法解决时,他如此说道。
java开发人员还喜欢说:这个不应该由jdk或某某框架完成,而应该是由勇敢、勤劳、智慧的您来编写实现的。

以下都是我在开发java项目时,遇到的一些问题,可能也有写得不对的地方,望指正。
遇到很多问题,一时间无法全部拿出来讨论,就随便列举了几条。

1."abc"=="abc"返回的结果是false,很多初学java的都要在这个问题很浪费很多时间,因为会非常自信的以为这里会返回true,根本不会想到原来问题出在这里。网上看到有贴子讨论过这个问题,说什么java是纯面向对象的语言,==操作符是比较地址什么的,而"abc"是引用,所以不能使用==操作符进行比较,而应该使用equals方法来进行比较,会犯这种错误的,多半是因为自己基础不牢,却还来说java的不是。我看到一个人说的一个例子,很能表示我的感想,是这么说的:有一天我去到一个餐厅,因为餐厅门口有一滩水,导致路面很滑,我不小心摔倒了,于是我找来餐厅经理,追究其责任,结果餐厅经理告诉我,这是因为我自己走路的姿势不对,所以滑倒了,与餐厅无关。

2.为什么没有get;set;属性,而是使用getXX();setXX()方法来代替,反射难道不要成本吗?
我所了解到的struts\spring\hibernate里都大量用到这种方式,比如struts中的vo对象,里面若有个getUsername(),在页面里可以用<s:property value="username"/>来取值,这中间我想应该是用反射来找到getUsername()方法,再取得其值的吧,同样的spring\hibernate中也大量用到这种方式,我想问,反射不是说很低效的吗?

3.做个自定义标签还要自己写个tld配置文件,有时在看一些java的相关书籍上面提到零配置时,我就觉得非常可笑,不知道所谓零配置的精神到底体现在哪里?也许写个配置文件也并没有那么难,但关键问题在于,从技术上来讲这个tld明显是可以不要的啊,tld里面主要就描述了这个tag叫什么名字有哪些属性,分别是什么类型,这些信息完全可以在类里面表示,只要是实现Tag接口的类就被自动识别为自定义标签这样不好吗?通过识别类里有哪些getXX();setXX();(更好的方案是有get;set;属性)来确定这个自定义标签有哪些属性,又分别是什么类型这样不好吗?为什么还要多此一举搞个tld配置文件?
还有个问题是,如果我写了个MyTag的类,继承了某个自定义标签类,我还要为MyTag写个相应的tld配置,我不知道将来还有没有其他开发人员会继承我的MyTag,也许就算我热烈欢迎别人来继承我的MyTag,但当别人看到我MyTag里近三四十个getXX();setXX();之后,想到要为其写上相应的tld配置文件而望而生怯吧。

4.数据访问在我看来,应该是个很简单的事情,简单来就,就是执行SQL语句,复杂一点,就再加上实体映射,所有框架解决的问题,首先就是要易于使用,在使用过hibernate之后,我感觉它太复杂了,我在.net里有一个数据访问层,只需要在指定的配置文件中配置连接字符串,就可以在程序中的任何地方调用DbHelper.Execute(sql)、DbHelper.ExecuteDataSet(sql)、DbHelper.ExecuteDataTable(sql)了,使用起来非常简单,当然也有实体映射,DbHelper.save(entity)、DbHelper.delete(entity or key)、DbHelper.select(条件)这一组方法就可以操作实体对象,select返回的是实体列表,实体通过元属性设置其关联的表和字段,这中间除了连接字符串之外,是没有任何其它配置文件的。相比之下,hibernate咋需要这么多配置文件?我知道hibernate也可以配置注解,就不需了hbm配置文件了,但即使这样,据我了解依旧还是需要很多除连接字符串之外的其它的相关配置文件。

5.话说java也有这么多年了,hibernate也有这么多年了,到底是我不会用,还是它真的就是这样的,hibernate对于存储过程的支持,实在让我抓狂,居然不支持存储过程,在网上寻找hibernate调用存储过程,得到的答案多数就是越过hibernate,而仅仅从hibernate中取得一个connection,再使用jdbc的方式调用存储过程,这样做存在一个问题,事务不能得到控制了,由于我还比较水,hibernate的事务控制又是暗箱操作的,好像是只要在service层中写的业务代码就都在一个事务中,所以我无法让我的存储过程调用和hibernate业务代码串在一个事务当中,而很多情况下,我是想要让它们一个失败就全部失败的。
除此之外,也有不越过hibernate而调用存储过程的办法,有两个,也是要写配置文件,一个是必须要有返回的结果集,我就很纳闷,为什么一定要有结果集,我的很多存储过程就只是处理一些数据,不需要返回结果集的,最难受的是oracle的存储过程其实不支持返回结果集,必须使用一种变态的游标方式返回,这么做我会感觉到极其反胃。另一个办法是通过修改实体在insert\update\delete时的默认行为,比如我在insert一个员工时,本来应该是执行sql语句insert into employee values (?,?,?,?)的,我可以通过配置文件修改这个默认行为,改成{call myproc(?,?,?,?)},这种方式显然也不是我想要的,我只想调用一个存储过程,执行一个业务的处理。以上两种方式是会被暗箱操作的事务所管理的,但并不能满足我的需求,我要怎么办?

6.数据访问的结果集对象ResultSet、RowSet、CachedRowSet等没有得到广泛的应用,各个框架更多的是倾向于支持实体列表,这么做导致出现一个问题,那就是我只能返回已知结构的结果集,若想要临时返回个东西还必须要在实体中添加相应的属性getXX();setXX();方法,比如在hibernate中,要访问员工表,员工表中本来只有部门ID,没有部门名称,你想要有部门名称,就必须在员工实体中添加一个deptName的属性,要所有的结果都是已知结构的,这样很痛苦,如果不返回到实体列表中,也可以返回到 ArrayList<Object[]> 中,但这样的数据没有列名称,不明白为什么不直接查询到ResultSet中,然后让更多的框架支持ResultSet,比如struts,在写页面使用struts标签时,可以像操作实体列表一样操作ResultSet。
<s:iterator id="myResultSet">...</s:iterator>,(还是本来就支持,只是我不会?那就不好意思啦!)只是希望让更多的框架支持未知结构的结果集,让程序员事先设计好结果集的结构是很累人的,就算是代码生成,也只能生成数据库里的每一张表对应的实体,但往往我们需要select unkownSchema from myTable得到未知结构的结果集,并不是每次都select *。

7.再说ResultSet,之所以不直接用这个,而使用实体列表来代替,我想是不是也间接的说明了,ResultSet这个类不方便使用,.net中的DataSet和DataTable就得到大量使用,因为它们方便好用实用。可能最大差别的地方就在于,DataSet是断开式的存在于内存中的微型数据库,而ResultSet只是连接式的数据库读取器,相当于.net中的DataReader,必须保持连接才能读数据,我知道有CachedRowSet可以断开式的存储数据在内存中,好吧,这个就不是问题了。但另一个问题在滋扰着我,做为存储结果集的容器,提供给我们操作这个结果集的方法太少了,甚至取得该结果集的总行数的方法,我们都需要开动小脑筋,这么写:rs.last(); int count = rs.getRow(); rs.first() 负责的话,它需要至少三句代码才能取到总行数。也许这只是小问题,这个或许应该由勇敢、勤劳、智慧的我们来实现。

8.在我看来,struts最大的意义在于,它使得每个jsp页面都有了一个与之对应的java类的方法,也就是那个action方法。你一定会跟我说,struts的功能并不只如此,但我说,我见过的很多(小公司)的项目,struts的意义就只是这样的,我想像在我们国家,还有成千上万的使用java技术的公司,struts对于他们的意义,也就是让jsp有了后台代码。如果仅仅只是如此,为何不由官方提供,直接让jdk支持,让struts的先进来弥补jdk的落后吗?只会欲盖弥彰。
或者你会说,即便struts就是提供了让每个jsp页面都有一个与之对应的action方法,这也非常伟大了,做到这一点,已经彻底改变了人们开发web项目的方式,由原来的业务代码和页面混在一起,变成解偶分离,非常成功了。我想说,不要拿你十年前的荣耀到今天再来说了,已经out的不行了。

9.再说myeclipse,这个ide在java体系中几乎成为标准,我见过的所有java开发人员都是使用这个IDE,但相比之下,它与visual studio就相差太多了,性能就不说了,如果不做优化,那是慢得想死,话说为什么不能在其一发布出来的默认设置就是最优化的呢?如果我们需要什么插件组件,再自己加载,这样不是更清楚明白吗?
另外myeclipse的插件安装方式实在让我汗颜,6.x,7.x,8.x这几个版本的插件安装方式各不相同,我在想,为什么不能直接双击安装?vss2005就是直接双击安装。至今我还没搞清楚svn插件怎么安装的,好吧,我是很水,那个插件的安装有时要复制文件到指定目录,有时要启动myeclipse之后,选择help菜单下的software updates,有时候又要选择什么myeclipse configuration center,有时候要连接互联网在线操作,更甚者,给你个java文件,要你编译成class文件,再按步骤操作,我是服了。


10.out输出参数,部分类,扩展方法,lamuda表达式这些非常好的东西,java都没有,还是我不会吗?望指正。
spring,其实我现在还不知道它是干嘛的,好吧,这是我的罪。

望展开激烈、火爆的讨论,可以使用分庭伉礼、围魏救赵、十面埋伏、单挑、围殴等各种手段。


...全文
21636 674 打赏 收藏 转发到动态 举报
写回复
用AI写文章
674 条回复
切换为时间正序
请发表友善的回复…
发表回复
wp19901108 2014-02-22
  • 打赏
  • 举报
回复
有些意思啊
我喜欢吃包子 2014-02-12
  • 打赏
  • 举报
回复
留个痕迹,下次有时间再够来看看~~~~~
叶半欲缺 2014-02-11
  • 打赏
  • 举报
回复
一.对于== 和equals确实挺复杂的,不过有一句话也没错==比较的是值和地址,equals比较的是值。 可能楼主理解不深,举得例子不一样。我就借楼上有个举得列子来说说: String str1 = "abc";//变量会放在桟内存str1,值会放在堆内存abc String str2 = "abc";//这时它会先看看堆内存有没有abc,要是有就不创建了,会直接指到堆内存里面的abc的那个地址。。。所以str1和str2指的是同一个堆内存地址中的同一个值,顾相等== String str = new String("abc");//其实是创建了两个对象,一个是str,一个是new String("");第一个值是new String..,第二个值是abc;顾str其实是一个对象所以与str1不相等==。在这里你也可以把String看是是一个类。 二.你说的svn插件安装,其实下载一个svn-eclipse-site.zip这个就可以了, 1.》打开eclipse---选择‘help’---点'Install new Software'--- 2.》在打开的对话框Install---选择'Add'----弹出'Add Repository'对话框--- 3.》在Location的‘Archive’按钮选择本地的‘svn-eclipse-site-1.6.10.zip’(or也就是site插件)---点击‘ok’- 4.》'select All'全选---下一步(点两次)-有对话框弹出选择‘是orYES’--接收--完成 5.》然后同意重启下就可以,SVN就配置到SVN上了 自己操作下试试,应该会很容易上手,我觉得他这样做是为了他的跨平台性考虑的,你说的vd,双击,我觉得也有局限性,针对window可能方便点
莫_问 2014-02-08
  • 打赏
  • 举报
回复
引用 669 楼 ysblue 的回复:
[quote=引用 37 楼 mni2005 的回复:] 我来替lz说句公道话:


public class test {

	public static void main(String[] args) {
		String str1 = new String("abc");
		String str2 = new String("abc");
		System.out.print(str1 == str2);
	}

}

public class test {

	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		System.out.print(str1 == str2);
	}

}

大家看看这两个代码的执行结果,再批判lz,武断的批判lz,只能说明你们java基础更是半杯水,认为你还可以的话,把出现上面的原因解释下。
我可以很明确的告诉你 == 运算是比较的内存地址,两个String对象的内存地址,是肯定不等的. 第二种情况,你明白什么是String pool的概念么?第二种情况下,String相当于基本类型在使用, java会把"abc"字符串放入pool里然后str1,str2分别指向pool里面的abc内存地址,然后结果就很 明了,这个有什么疑惑么?[/quote] 兄弟,你刨坟啊???
水华_Lin 2014-02-08
  • 打赏
  • 举报
回复
小白过来学习的
lifeflowers 2014-01-28
  • 打赏
  • 举报
回复
引用 37 楼 mni2005 的回复:
我来替lz说句公道话:


public class test {

	public static void main(String[] args) {
		String str1 = new String("abc");
		String str2 = new String("abc");
		System.out.print(str1 == str2);
	}

}

public class test {

	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		System.out.print(str1 == str2);
	}

}

大家看看这两个代码的执行结果,再批判lz,武断的批判lz,只能说明你们java基础更是半杯水,认为你还可以的话,把出现上面的原因解释下。
我可以很明确的告诉你 == 运算是比较的内存地址,两个String对象的内存地址,是肯定不等的. 第二种情况,你明白什么是String pool的概念么?第二种情况下,String相当于基本类型在使用, java会把"abc"字符串放入pool里然后str1,str2分别指向pool里面的abc内存地址,然后结果就很 明了,这个有什么疑惑么?
lifeflowers 2014-01-28
  • 打赏
  • 举报
回复
引用 4 楼 daniellitoc 的回复:
1."abc"=="abc"返回的结果是false 头一次听说,你连一门语言的数据结构都不懂,还大言不惭的谈起十宗罪!
我只知道,"abc"== new String("abc")会可能会返回false,可能是我太水了
wenjie4892543 2014-01-13
  • 打赏
  • 举报
回复
说句,,,任何事物都有好的或者不好,,个人观点不同,,除开技术来说,,,LZ说的可能是他个人观点有正确可能有不正确,无可厚非,,谁也不是天生就懂,,既然大家都说第一个问题,,那就说说,,确实很多人看到第一个问题,,可能 大部分人都犯过这个错误,, == 和 equals的区别 可能有很多人 区分有点难度,不是所有人都懂吧,,包括 我 ,, 我 都是 只用 equals 而 尽量不用 == 、、 区分:只比较值的时候 用 == ,, 需要 比较 值和 内存地址 时 用 equals
sca4441479 2013-11-26
  • 打赏
  • 举报
回复
好热闹啊~~
diyyue 2013-11-24
  • 打赏
  • 举报
回复
看到lz第一条就不想往下看了
BD-世界 2013-11-22
  • 打赏
  • 举报
回复
引用 608 楼 Tz_Sword 的回复:
我只看到 太多的系统采用java了。。。 楼主你怎么说呢?
java几乎全免费啊
BD-世界 2013-11-22
  • 打赏
  • 举报
回复
第一次听说android跟java没关系,好吧,我们java的都白干了
cat_猫 2013-11-22
  • 打赏
  • 举报
回复
这帖该删,误导人。
不泪之城 2013-10-08
  • 打赏
  • 举报
回复
看到第三条的时候就没接着看下去了,楼主没有感觉到深入学习java是中乐趣,而是放在抱怨上了,并没有弄透java的实质就来抱怨了
刘正权 2013-09-14
  • 打赏
  • 举报
回复
引用 18 楼 zhouyou96 的回复:
非常抱歉,第1点关于"abc"=="abc"返回false是我搞错了,在java里是返回true的,我没有经过实验就这么说了,非常抱歉。之所以会这么说,是因为不记得是哪一种,因为我使用了==进行了字符串的比较,结果并没有返回我相要的结果,然后请教老人,老人们就训诫道:最好使用equals进行比较,而不要使用==,故有此感慨。
我也记得有 “abc”==“abc” 这回事儿。好像是学习JavaSE的时候。
浮缈 2013-08-30
  • 打赏
  • 举报
回复
狭隘的眼光 不解释。什么都不懂还冲什么大神。如果java真的存在这么多的问题,世界巨头会允许它成为目前占有市场份额最大的语言么。还是说 你认为你比真的大神更牛逼了。自己不会用java就不要多发言。还十宗罪了。我看只有你有一宗罪---------SB罪
lkq_david 2013-06-05
  • 打赏
  • 举报
回复
"abc"=="abc"返回的是true,说这话的时候要先运行下看看
七日断肠散 2013-05-30
  • 打赏
  • 举报
回复
1."abc"=="abc"返回的结果是false 这个在C中字符串比较也不是用==吧,而是用strcmp函数比较,这个大家都懂的.至于为什么不用“==”既然这样必然有它的道理,其他的我都不懂,刚学的.
蝴蝶Poj 2013-05-24
  • 打赏
  • 举报
回复
楼主能总结出来这些东西,如果是原创的话,很不错。顶你。
小小的新手 2013-05-22
  • 打赏
  • 举报
回复
引用 8 楼 ticmy 的回复:
[Quote=引用 6 楼 zhouyou96 的回复:] 引用 4 楼 daniellitoc 的回复: 1."abc"=="abc"返回的结果是false 头一次听说,你连一门语言的数据结构都不懂,还大言不惭的谈起十宗罪! 在java里"abc"=="abc"确实是返回false,按常规思维理解,它应该要返回true才对,你所说的什么数据结构,什么机制的,我不管,我也不想管,我只知道一门语言应该要人性化。不要把它的不人性化用一句:“这就…… [/Quote] 楼主先把这个代码执行一遍再来说话:
public class Test {
	public static void main(String[] args) {
		System.out.println("abc"=="abc");
	}
}
楼主悲剧啊…… 在哪运行的啊?会是false?
加载更多回复(637)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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