|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在性能方面,在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">[16]2areturnLinenumbers:[pc:0,line:7]Localvariabletable:[pc:0,pc:3]local:thisindex:0type:Child//Methoddescriptor#18()Ljava/lang/Object;//Stack:1,Locals:1bridgesyntheticjava.lang.Objectx();0aload_0[this]1invokevirtualChild.x():java.lang.String[19]4areturnLinenumbers:[pc:0,line:1
复制代码 在字节码里T实在就是Object罢了。这了解起来就简单多了。
syntheticbridge办法是由编译器天生的,由于在特定的挪用点Parent.x()署名的前往范例应该是Object范例。假如利用了泛型却没有这个bridge办法的话,代码的二进制情势就没法兼容了。因而,修正JVM以撑持这个特征貌似更简单一些(这特地还完成了协变前往),看起来还挺不错的吧?
你有深切懂得过Java言语的标准和外部完成吗?这里有很多很成心思的工具。
3.它们都是二维数组!
- classTest{int[][]a(){returnnewint[0][];}int[]b()[]{returnnewint[0][];}intc()[][]{returnnewint[0][];}}
复制代码 是的,没错。大概你没法即刻说出上述办法的前往范例是甚么,但它们切实其实都是一样的!一样的另有上面这段代码:- 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";}}4
复制代码 8.Java也有范例别号
在别的言语中(好比说Ceylon,界说范例别号十分复杂:- abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}5
复制代码 如许所界说出来的People范例能够和Set瓜代利用:- abstractclassParent<T>{abstractTx();}classChildextendsParent<String>{@OverrideStringx(){return"abc";}}6
复制代码 Java中没法在最外层完成范例别号。不外我们能够在类大概办法的感化域内来完成这点。假定我们如今以为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打包应用程序是一样的。按照你的想法,你是不是也希望服务器都整合由一家公司提供呢? |
|