JAVA编程:Java不为人知的10个原形仓酷云
在性能方面,在windows平台下,.net网页编程可能是占强项,要是把.net网页编程放在sun开发的操作系统上去运行呢?根本就运行不了,.net网页编程对其它操作系统的支持也很弱,性能也可能比不上java。你是否是一入手下手就用Java来编程的呢?还记妥当年它还被称为"Oak",OO仍是抢手的话题,C++的用户以为Java没有远景,applets还只是个小玩意,菊花也仍是一莳花的时分吗?我敢赌博上面最少有一半是你不分明的。这周我们来看一下跟Java的外部完成相干的一些奇妙的事变。
1.实在基本没有受反省非常这回事
没错!JVM压根儿就不晓得有这个工具,它只存在于Java言语里。
现在人人都供认受反省非常就是个毛病。正如BruceEckel比来在布拉格的的GeeCON集会上所说的,除Java外没有其余言语会利用受反省非常这类工具,即便是Java8的新的StreamsAPI中也不再利用这一非常了(否则当你的lambda表达式顶用到IO大概JDBC的话就得疾苦逝世了)。
怎样能证明JVM的确不晓得这个非常?看下上面这段代码:
publicclassTest{//Nothrowsclauseherepublicstaticvoidmain(String[]args){doThrow(newSQLException());}staticvoiddoThrow(Exceptione){Test.<RuntimeException>doThrow0(e);}@SuppressWarnings("unchecked")static<EextendsException>voiddoThrow0(Exceptione)throwsE{throw(E)e;}}这不但能经由过程编译,并且也切实其实会抛出SQLException非常,而且完整不必要用到Lombok的@SneakyThrows注解。
更进一步的剖析能够看下这篇文章,大概StackOverflow上的这个成绩。
2.分歧的前往范例也能够举行办法重载
这个应当是编译不了的吧?
classTest{Objectx(){return"abc";}Stringx(){return"123";}}是的。Java言语其实不同意统一个类中呈现两个重写等价("override-equivalent")的办法,不论它们的throws子句和前往范例是否是分歧的。
不外等等。看下Java文档中的Class.getMethod(String,Class...)是怎样说的。内里写道:
只管Java言语不同意一个类中的多个不异署名的办法前往分歧的范例,可是JVM其实不克制,以是一个类中大概会存在多个不异署名的办法。这增加了假造机的天真性,能够用来完成很多言语特征。好比说,能够经由过程bridge办法来完成协变前往(covariantreturn,即虚办法能够前往子类而纷歧定得是基类),bridge办法和被重写的办法具有不异的署名,但却前往分歧的范例。哇,这倒有点意义。现实上,上面这段代码就会触发这类情形:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}看一下Child类所天生的字节码:
//Methoddescriptor#15()Ljava/lang/String;//Stack:1,Locals:1java.lang.Stringx();0ldc<String"abc">2areturnLinenumbers:Localvariabletable:local:thisindex:0type:Child//Methoddescriptor#18()Ljava/lang/Object;//Stack:1,Locals:1bridgesyntheticjava.lang.Objectx();0aload_01invokevirtualChild.x():java.lang.String4areturnLinenumbers:在字节码里T实在就是Object罢了。这了解起来就简单多了。
syntheticbridge办法是由编译器天生的,由于在特定的挪用点Parent.x()署名的前往范例应该是Object范例。假如利用了泛型却没有这个bridge办法的话,代码的二进制情势就没法兼容了。因而,修正JVM以撑持这个特征貌似更简单一些(这特地还完成了协变前往),看起来还挺不错的吧?
你有深切懂得过Java言语的标准和外部完成吗?这里有很多很成心思的工具。
3.它们都是二维数组!
classTest{int[][]a(){returnnewint[];}int[]b()[]{returnnewint[];}intc()[][]{returnnewint[];}}是的,没错。大概你没法即刻说出上述办法的前往范例是甚么,但它们切实其实都是一样的!一样的另有上面这段代码:
classTest{int[][]a=;int[]b[]=;intc[][]=;}你是否是以为这有点猖狂?相像一下假如再用上JSR-308/Java8中的范例注解吧。各类写法不可胜数。
@Target(ElementType.TYPE_USE)@interfaceCrazy{}classTest{@Crazyint[][]a1=;int@Crazy[][]a2=;int[]@Crazy[]a3=;@Crazyint[]b1[]=;int@Crazy[]b2[]=;int[]b3@Crazy[]=;@Crazyintc1[][]=;intc2@Crazy[][]=;intc3[]@Crazy[]=;}范例注解。奥秘之极,壮大之极。大概这么说:
敬爱的同事,提交完这段代码下月我就要休假了:
这些写法究竟有甚么用,这个就留给你本人渐渐探究吧。
4.你基本就不懂前提表达式
那末,你觉得前提表达式你就很懂得了吗?我告知你吧,你压根就不懂。良多人都以为上面两段代码是一样的:
Objecto1=true?newInteger(1):newDouble(2.0);它和上面这个是一样的吧?
Objecto2;if(true)o2=newInteger(1);elseo2=newDouble(2.0);不是的。我们来测试下。
System.out.println(o1);System.out.println(o2);这段代码会输入:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}0没错,前提操纵符在"需要"的时分会举行数值范例的提拔,这个“需要”得加上一个重重的引号。你能想到上面这段程序竟然会抛出一个空指针非常吗?
classTest{Objectx(){return"abc";}Stringx(){return"123";}}1想懂得更多请参考这里。
5.你也不懂复合赋值操纵符
很奇异吧?我们再来看下这两段代码:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}2明显他们都是一样的嘛。不外,实在否则。Java言语标准中是这么说的:
E1op=E2情势的复合赋值表达式等价于E=(T)((E1)op(E2)),这里的T的范例是E1,E1仅会举行一次求值。这太奇奥了。我想援用一下PeterLawre在StackOverflow下面的一个回覆:
这类范例的范例转换经由过程*=大概/=能够很简单地申明:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}3大概
classTest{Objectx(){return"abc";}Stringx(){return"123";}}4大概
classTest{Objectx(){return"abc";}Stringx(){return"123";}}5又大概:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}6那末这么做究竟有甚么用?你能够在你的程序里试一下char范例的范例转换和乘法操纵。由于你懂的,这够装逼。。
6.随机整数
这更像是一个头脑急转弯。先不要发急看谜底。看你能不克不及本人弄定。当运转以下这段程序时:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}7“偶然”它会输入如许的了局:
classTest{Objectx(){return"abc";}Stringx(){return"123";}}8这特么大概么?
.........
要剧透了,谜底就要来了。。
........
好吧,谜底在这里,你得经由过程反射重写失落JDK的Integer内里的缓存,然后再利用主动装箱和拆箱的功效。不要真的这么做!换句话说,我们再夸大一次:
敬爱的同事,提交完这段代码,我下月就休假了哦(你看不懂可别怪我):
7.GOTO
这是我最津津有味的。Java实在也有GOTO!敲下代码看看
classTest{Objectx(){return"abc";}Stringx(){return"123";}}9它的输入是
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}0这是由于goto是一个预留的关头字,万一今后有效呢。。。
不外这还不是重点。成心思的是你能够经由过程break,continue和标签块来完成goto的功效:
跳转到后面:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}1它的字节码是:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}2跳转到前面:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}3它的字节码是:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}48.Java也有范例别号
在别的言语中(好比说Ceylon,界说范例别号十分复杂:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}5如许所界说出来的People范例能够和Set瓜代利用:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}6Java中没法在最外层完成范例别号。不外我们能够在类大概办法的感化域内来完成这点。假定我们如今以为Integer,Long的名字看着不爽了,但愿能更冗长些:I和L。这很复杂:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}7下面这段程序中,在Test类的感化域内,Integer的别号是I,而在x办法内,Long的是L。我们能够如许来挪用下面的办法:
abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}8这固然不是甚么正式的别号的体例。在本例中,Integer和Long都是final范例,也就是说范例I和L就是真正意义上的别号(算是吧。由于它只要一种赋值相容(assignment-compatibility)的体例)。假如你利用的长短final范例时(好比说Object),那你用的实在就是泛型罢了了。
这类虫篆之技就先说到这吧。如今我们来说点成心义的!
用winrar打包j2ee的程序和用IDE打包应用程序是一样的。按照你的想法,你是不是也希望服务器都整合由一家公司提供呢? 在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。 是一种语言,用以产生「小应用程序(Applet(s)) 你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。 你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。 J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。 Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。 自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。 你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。 多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
页:
[1]