下载|安装|配置|更新

下载|安装|配置|更新

免费下载、安装与配置、新版发布等
Java EE开发

Java EE开发

Spring、WebSphere、Maven相关、EJB、JSP、XDoclet等
移动开发

移动开发

iOS、Android跨平台移动应用开发
SDC

SDC

新一代软件分发管理神器!支持MyEclipse、Eclipse、IntelliJ、WebStorm等热门IDE.
综合讨论区

综合讨论区

意见、吐槽、属于Java人的轻松乐园…

myeclipse2014连接sqlserver2014

回复

下载|安装|配置|更新feng1028775672 发起了问题 • 2 人关注 • 0 个回复 • 40 次浏览 • 2015-11-09 08:45 • 来自相关话题

MyEclipse10打开提示错误,An error has occurred,See the log file

回复

下载|安装|配置|更新Lundy 发起了问题 • 1 人关注 • 0 个回复 • 113 次浏览 • 2015-11-08 15:52 • 来自相关话题

myeclipse-spring-2014-GA 破解失败

回复

下载|安装|配置|更新txx 发起了问题 • 1 人关注 • 0 个回复 • 43 次浏览 • 2015-11-06 18:55 • 来自相关话题

myeclipse 2015怎么查看授权的具体版本?

下载|安装|配置|更新besy 回复了问题 • 3 人关注 • 1 个回复 • 90 次浏览 • 2015-11-05 14:35 • 来自相关话题

macbook pro 稳定2.0版MyEclipse 加入SVN插件后,启动就卡死,无响应

综合讨论区besy 回复了问题 • 2 人关注 • 1 个回复 • 56 次浏览 • 2015-11-05 14:31 • 来自相关话题

总是弹出skyway错误 怎么解决啊?

回复

下载|安装|配置|更新默默低头 发起了问题 • 1 人关注 • 0 个回复 • 8 次浏览 • 2015-11-03 20:54 • 来自相关话题

myeclipse8.5

回复

MyEclipse IDE公告xuling 发起了问题 • 2 人关注 • 0 个回复 • 155 次浏览 • 2015-11-03 20:41 • 来自相关话题

被公认为最好的Java开发平台之一IntelliJ IDEA最新发布2015版啦!欢迎围观下载

MyEclipse IDE公告besy 发表了文章 • 0 个评论 • 147 次浏览 • 2015-11-03 16:29 • 来自相关话题

作为唯一可以和MyEclipse抗衡的另一款Java IDE,IntelliJ IDEA一直被公认为是最好的Java开发平台之一。

下面就一起来see一see 2015版都有哪些新变化:

## lambda调试 ##

如果你添加断点的行有lambda表达式的话,IDE会提示你具体在什么地方停止。当你使用Step Into或Run to Cursor,IDE会在相应的lambda表达式停止调试。

## 强制返回 ##

有了新的调试器操作Force Return,你可以强制从当前方法的返回,而不需执行任何其它指令。如果该方法返回一个值,你必须指定它。如果该方法有try-finally模块,你就可以选择是否执行它们。

## 改进测试UI ##

现在整个测试运行器工具窗口提供包括所有语言,完整的在线统计数据,垂直布局,测试结果历史记录和导出/导入操作的统一接口。

## 查找路径即时预览 ##

为了使“Find in Path”操作反应更灵敏,我们增加了一个预览选项卡来显示前100个实时查询结果。

[完整图文更新说明戳这里](http://www.evget.com/article/2015/11/3/22880.html) | [下载戳这里](http://www.evget.com/product/2992/download) 查看全部
作为唯一可以和MyEclipse抗衡的另一款Java IDE,IntelliJ IDEA一直被公认为是最好的Java开发平台之一。

下面就一起来see一see 2015版都有哪些新变化:

## lambda调试 ##

如果你添加断点的行有lambda表达式的话,IDE会提示你具体在什么地方停止。当你使用Step Into或Run to Cursor,IDE会在相应的lambda表达式停止调试。

## 强制返回 ##

有了新的调试器操作Force Return,你可以强制从当前方法的返回,而不需执行任何其它指令。如果该方法返回一个值,你必须指定它。如果该方法有try-finally模块,你就可以选择是否执行它们。

## 改进测试UI ##

现在整个测试运行器工具窗口提供包括所有语言,完整的在线统计数据,垂直布局,测试结果历史记录和导出/导入操作的统一接口。

## 查找路径即时预览 ##

为了使“Find in Path”操作反应更灵敏,我们增加了一个预览选项卡来显示前100个实时查询结果。

[完整图文更新说明戳这里](http://www.evget.com/article/2015/11/3/22880.html) | [下载戳这里](http://www.evget.com/product/2992/download)

myeclipse 10.6右键项目,无configure功能

Java EE开发javatom 回复了问题 • 2 人关注 • 1 个回复 • 28 次浏览 • 2015-11-02 16:46 • 来自相关话题

【年终钜惠】MyEclipse个人授权全场8.5折!

MyEclipse IDE公告besy 发表了文章 • 0 个评论 • 72 次浏览 • 2015-11-02 11:47 • 来自相关话题

## 活动时间:11月1日-11月30日 ##
**MyEclipse个人授权全场8.5折促销!买3年以上还享额外优惠哦~**
[在线购买](http://www.myeclipsecn.com/buy/)>>

*在线下单后2-3个工作日内发货



一年一度的慧都年终促销隆重揭开帷幕,全场产品(个别产品除外)通选两款即可享全单8.5折,大疆无人机、iPhone 6S等豪华大礼满额就送,最热销的DevExpress、FastReport、Aspose等众多产品抄底价促销……活动期间关注 “慧都控件”微信公众号转发相关文章,还有代金券、现金红包等好礼相送!机不可失,时间有限,欢迎您的到来!活动详情:http://www.evget.com/zt/2015/promotion.html 查看全部
## 活动时间:11月1日-11月30日 ##
**MyEclipse个人授权全场8.5折促销!买3年以上还享额外优惠哦~**
[在线购买](http://www.myeclipsecn.com/buy/)>>

*在线下单后2-3个工作日内发货



一年一度的慧都年终促销隆重揭开帷幕,全场产品(个别产品除外)通选两款即可享全单8.5折,大疆无人机、iPhone 6S等豪华大礼满额就送,最热销的DevExpress、FastReport、Aspose等众多产品抄底价促销……活动期间关注 “慧都控件”微信公众号转发相关文章,还有代金券、现金红包等好礼相送!机不可失,时间有限,欢迎您的到来!活动详情:http://www.evget.com/zt/2015/promotion.html

MyEclipse自动关闭

下载|安装|配置|更新春花秋实 回复了问题 • 2 人关注 • 2 个回复 • 44 次浏览 • 2015-10-28 19:28 • 来自相关话题

项目引用:被引用的class或者xml找不到

回复

Java EE开发yunlian0621 发起了问题 • 1 人关注 • 0 个回复 • 14 次浏览 • 2015-10-27 16:26 • 来自相关话题

【版本升级】MyEclipse 2015 CI 16发布

下载|安装|配置|更新besy 发表了文章 • 2 个评论 • 230 次浏览 • 2015-10-27 11:20 • 来自相关话题

MyEclipse 2015 CI 16版本来啦!新版包括Slack Integration,Gerrit Tools,改进了JavaScript功能,以及其他一些bug修复。

## Slack Integration ##

新版本集成了Slack,你只需要注册一个Slack帐号然后就可以发送和接收代码片段。你甚至不需要登录Slack就可以直接在Eclipse中查看分享的代码。

## Gerrit Tools ##

如果你用Gerrit审查代码或者Git存储库管理,会感受到整个过程相当的流畅,你可以轻松的在多个功能模块间切换。此外,在提交代码前你可以得到高质量的代码和测试体验。

## [查看详细更新说明](http://www.myeclipsecn.com/lea ... ci-16/) | [下载](http://www.myeclipsecn.com/bbs/?/question/16)## 查看全部
MyEclipse 2015 CI 16版本来啦!新版包括Slack Integration,Gerrit Tools,改进了JavaScript功能,以及其他一些bug修复。

## Slack Integration ##

新版本集成了Slack,你只需要注册一个Slack帐号然后就可以发送和接收代码片段。你甚至不需要登录Slack就可以直接在Eclipse中查看分享的代码。

## Gerrit Tools ##

如果你用Gerrit审查代码或者Git存储库管理,会感受到整个过程相当的流畅,你可以轻松的在多个功能模块间切换。此外,在提交代码前你可以得到高质量的代码和测试体验。

## [查看详细更新说明](http://www.myeclipsecn.com/lea ... ci-16/) | [下载](http://www.myeclipsecn.com/bbs/?/question/16)##

干货分享!2015年MyEclipse使用教程最强盘点

下载|安装|配置|更新besy 发表了文章 • 4 个评论 • 346 次浏览 • 2015-10-26 15:47 • 来自相关话题

小伙伴们,2015年 MyEclipse 使用教程最强盘点来袭!看完本文,你将全面了解MyEclipse的强大之处,掌握正确打开MyEclipse的正确姿势:快捷键、常用配置、性能优化方法、基本使用教程、高级使用教程、常用技巧……让你摇身一变成为Java编程高手以及MyEclipse使用达人!

原文请移步>>
## [干货分享!2015年MyEclipse使用教程最强盘点](http://www.evget.com/article/2015/10/26/22822.html) ## 查看全部
小伙伴们,2015年 MyEclipse 使用教程最强盘点来袭!看完本文,你将全面了解MyEclipse的强大之处,掌握正确打开MyEclipse的正确姿势:快捷键、常用配置、性能优化方法、基本使用教程、高级使用教程、常用技巧……让你摇身一变成为Java编程高手以及MyEclipse使用达人!

原文请移步>>
## [干货分享!2015年MyEclipse使用教程最强盘点](http://www.evget.com/article/2015/10/26/22822.html) ##

MyEclipse Spring集团授权促销【买就送iPhone 6 Plus】

回复

MyEclipse IDE公告besy 发起了问题 • 1 人关注 • 0 个回复 • 50 次浏览 • 2015-10-21 14:48 • 来自相关话题

为何程序运行 JAVA 内存会不断增加

下载|安装|配置|更新fent 回复了问题 • 2 人关注 • 2 个回复 • 52 次浏览 • 2015-10-20 11:33 • 来自相关话题

16g pro 装装2015ci14 经常打开就卡死,请问大家有遇到相同情况的吗?求助,

下载|安装|配置|更新besy 回复了问题 • 3 人关注 • 2 个回复 • 48 次浏览 • 2015-10-20 11:11 • 来自相关话题

Http preview服务器端口号修改

回复

下载|安装|配置|更新xiaowan 发起了问题 • 1 人关注 • 0 个回复 • 19 次浏览 • 2015-10-19 22:11 • 来自相关话题

mac myeclipse 2015 未响应

下载|安装|配置|更新dcz_vip163 回复了问题 • 5 人关注 • 3 个回复 • 46 次浏览 • 2015-10-17 15:26 • 来自相关话题

我的电脑服务里找不到tomcat服务但任务管理器里却有进程

回复

下载|安装|配置|更新qqj1299737 发起了问题 • 1 人关注 • 0 个回复 • 13 次浏览 • 2015-10-15 16:59 • 来自相关话题

【附示例】Java 程 序 员 必 知 的 8 大 排 序

综合讨论区besy 发表了文章 • 0 个评论 • 231 次浏览 • 2015-10-15 11:26 • 来自相关话题

8种排序之间的关系:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 68.png)

## 1、直接插入排序 ##

(1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排

好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数

也是排好顺序的。如此反复循环,直到全部排好顺序。

(2)实例

![请输入图片名称](http://my.csdn.net/uploads/201 ... 87.png)

(3)用java实现

{{{
package com.njue;

public class insertSort {
public insertSort(){
inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=1;i<a.length;i++){
int j=i-1;
temp=a[i];
for(;j>=0&&temp<a[j];j--){
a[j+1]=a[j]; //将大于temp的值整体后移一个单位
}
a[j+1]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 2、希尔排序(最小增量排序) ##

(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 15.png)

(3)用java实现

{{{
public class shellSort {
public shellSort(){
int a[]={1,54,6,3,78,34,12,45,56,100};
double d1=a.length;
int temp=0;
while(true){
d1= Math.ceil(d1/2);
int d=(int) d1;
for(int x=0;x<d;x++){
for(int i=x+d;i<a.length;i+=d){
int j=i-d;
temp=a[i];
for(;j>=0&&temp<a[j];j-=d){
a[j+d]=a[j];
}
a[j+d]=temp;
}
}
if(d==1)
break;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 3.简单选择排序 ##

(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;

然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 19.png)

(3)用java实现

{{{
public class selectSort {
public selectSort(){
int a[]={1,54,6,3,78,34,12,45};
int position=0;
for(int i=0;i<a.length;i++){

int j=i+1;
position=i;
int temp=a[i];
for(;j<a.length;j++){
if(a[j]<temp){
temp=a[j];
position=j;
}
}
a[position]=a[i];
a[i]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 4、 堆排序 ##

(1)基本思想:堆排序是一种树形选择排序,是对直接选择排序的有效改进。

堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。

(2)实例:

初始序列:46,79,56,38,40,84

建堆:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 48.png)

交换,从堆中踢出最大数

![请输入图片名称](http://my.csdn.net/uploads/201 ... 47.png)

![请输入图片名称](http://my.csdn.net/uploads/201 ... 88.png)

依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。

(3)用java实现

{{{
import java.util.Arrays;

public class HeapSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public HeapSort(){
heapSort(a);
}
public void heapSort(int[] a){
System.out.println("开始排序");
int arrayLength=a.length;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆

buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);
System.out.println(Arrays.toString(a));
}
}

private void swap(int[] data, int i, int j) {
// TODO Auto-generated method stub
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
//对data数组从0到lastIndex建大顶堆
private void buildMaxHeap(int[] data, int lastIndex) {
// TODO Auto-generated method stub
//从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)/2;i>=0;i--){
//k保存正在判断的节点
int k=i;
//如果当前k节点的子节点存在
while(k*2+1<=lastIndex){
//k节点的左子节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex<lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}<p align="left">&nbsp;<span> </span>}</p><p align="left">&nbsp;&nbsp;&nbsp; }</p><p align="left">&nbsp;<span style="background-color: white; ">}</span></p>

}}}

## 5.冒泡排序 ##

(1)基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 67.png)

(3)用java实现

{{{
public class bubbleSort {
public bubbleSort(){
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}

}}}

## 6.快速排序 ##

(1)基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 95.png)

(3)用java实现

{{{
public class quickSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public quickSort(){
quick(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {

high--;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
public void _quickSort(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); //将list数组进行一分为二
_quickSort(list, low, middle - 1); //对低字表进行递归排序
_quickSort(list, middle + 1, high); //对高字表进行递归排序
}
}
public void quick(int[] a2) {
if (a2.length > 0) { //查看数组是否为空
_quickSort(a2, 0, a2.length - 1);
}
}
}
}}}

## 7、归并排序 ##

(1)基本排序:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 91.png)

(3)用java实现

{{{
import java.util.Arrays;

public class mergingSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public mergingSort(){
sort(a,0,a.length-1);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public void sort(int[] data, int left, int right) {
// TODO Auto-generated method stub
if(left<right){
//找出中间索引
int center=(left+right)/2;
//对左边数组进行递归
sort(data,left,center);
//对右边数组进行递归
sort(data,center+1,right);
//合并
merge(data,left,center,right);

}
}
public void merge(int[] data, int left, int center, int right) {
// TODO Auto-generated method stub
int [] tmpArr=new int[data.length];
int mid=center+1;
//third记录中间数组的索引
int third=left;
int tmp=left;
while(left<=center&&mid<=right){

//从两个数组中取出最小的放入中间数组
if(data[left]<=data[mid]){
tmpArr[third++]=data[left++];
}else{
tmpArr[third++]=data[mid++];
}
}
//剩余部分依次放入中间数组
while(mid<=right){
tmpArr[third++]=data[mid++];
}
while(left<=center){
tmpArr[third++]=data[left++];
}
//将中间数组中的内容复制回原数组
while(tmp<=right){
data[tmp]=tmpArr[tmp++];
}
System.out.println(Arrays.toString(data));
}

}
}}}

## 8、基数排序 ##

(1)基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 46.png)

(3)用java实现

{{{
import java.util.ArrayList;
import java.util.List;

public class radixSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,101,56,17,18,23,34,15,35,25,53,51};
public radixSort(){
sort(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public void sort(int[] array){

//首先确定排序的趟数;
int max=array[0];
for(int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}

int time=0;
//判断位数;
while(max>0){
max/=10;
time++;
}

//建立10个队列;
List<ArrayList> queue=new ArrayList<ArrayList>();
for(int i=0;i<10;i++){
ArrayList<Integer> queue1=new ArrayList<Integer>();
queue.add(queue1);
}

//进行time次分配和收集;
for(int i=0;i<time;i++){

//分配数组元素;
for(int j=0;j<array.length;j++){
//得到数字的第time+1位数;
int x=array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);
ArrayList<Integer> queue2=queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count=0;//元素计数器;
//收集队列元素;
for(int k=0;k<10;k++){
while(queue.get(k).size()>0){
ArrayList<Integer> queue3=queue.get(k);
array[count]=queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}

}
}}}

原文出处:http://blog.csdn.net/without08 ... 97916 查看全部
8种排序之间的关系:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 68.png)

## 1、直接插入排序 ##

(1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排

好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数

也是排好顺序的。如此反复循环,直到全部排好顺序。

(2)实例

![请输入图片名称](http://my.csdn.net/uploads/201 ... 87.png)

(3)用java实现

{{{
package com.njue;

public class insertSort {
public insertSort(){
inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=1;i<a.length;i++){
int j=i-1;
temp=a[i];
for(;j>=0&&temp<a[j];j--){
a[j+1]=a[j]; //将大于temp的值整体后移一个单位
}
a[j+1]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 2、希尔排序(最小增量排序) ##

(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 15.png)

(3)用java实现

{{{
public class shellSort {
public shellSort(){
int a[]={1,54,6,3,78,34,12,45,56,100};
double d1=a.length;
int temp=0;
while(true){
d1= Math.ceil(d1/2);
int d=(int) d1;
for(int x=0;x<d;x++){
for(int i=x+d;i<a.length;i+=d){
int j=i-d;
temp=a[i];
for(;j>=0&&temp<a[j];j-=d){
a[j+d]=a[j];
}
a[j+d]=temp;
}
}
if(d==1)
break;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 3.简单选择排序 ##

(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;

然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 19.png)

(3)用java实现

{{{
public class selectSort {
public selectSort(){
int a[]={1,54,6,3,78,34,12,45};
int position=0;
for(int i=0;i<a.length;i++){

int j=i+1;
position=i;
int temp=a[i];
for(;j<a.length;j++){
if(a[j]<temp){
temp=a[j];
position=j;
}
}
a[position]=a[i];
a[i]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
}}}

## 4、 堆排序 ##

(1)基本思想:堆排序是一种树形选择排序,是对直接选择排序的有效改进。

堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。

(2)实例:

初始序列:46,79,56,38,40,84

建堆:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 48.png)

交换,从堆中踢出最大数

![请输入图片名称](http://my.csdn.net/uploads/201 ... 47.png)

![请输入图片名称](http://my.csdn.net/uploads/201 ... 88.png)

依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。

(3)用java实现

{{{
import java.util.Arrays;

public class HeapSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public HeapSort(){
heapSort(a);
}
public void heapSort(int[] a){
System.out.println("开始排序");
int arrayLength=a.length;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆

buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);
System.out.println(Arrays.toString(a));
}
}

private void swap(int[] data, int i, int j) {
// TODO Auto-generated method stub
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
//对data数组从0到lastIndex建大顶堆
private void buildMaxHeap(int[] data, int lastIndex) {
// TODO Auto-generated method stub
//从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)/2;i>=0;i--){
//k保存正在判断的节点
int k=i;
//如果当前k节点的子节点存在
while(k*2+1<=lastIndex){
//k节点的左子节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex<lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}<p align="left">&nbsp;<span> </span>}</p><p align="left">&nbsp;&nbsp;&nbsp; }</p><p align="left">&nbsp;<span style="background-color: white; ">}</span></p>

}}}

## 5.冒泡排序 ##

(1)基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 67.png)

(3)用java实现

{{{
public class bubbleSort {
public bubbleSort(){
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}

}}}

## 6.快速排序 ##

(1)基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

(2)实例:

![请输入图片名称](http://my.csdn.net/uploads/201 ... 95.png)

(3)用java实现

{{{
public class quickSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public quickSort(){
quick(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {

high--;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
public void _quickSort(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); //将list数组进行一分为二
_quickSort(list, low, middle - 1); //对低字表进行递归排序
_quickSort(list, middle + 1, high); //对高字表进行递归排序
}
}
public void quick(int[] a2) {
if (a2.length > 0) { //查看数组是否为空
_quickSort(a2, 0, a2.length - 1);
}
}
}
}}}

## 7、归并排序 ##

(1)基本排序:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 91.png)

(3)用java实现

{{{
import java.util.Arrays;

public class mergingSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public mergingSort(){
sort(a,0,a.length-1);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public void sort(int[] data, int left, int right) {
// TODO Auto-generated method stub
if(left<right){
//找出中间索引
int center=(left+right)/2;
//对左边数组进行递归
sort(data,left,center);
//对右边数组进行递归
sort(data,center+1,right);
//合并
merge(data,left,center,right);

}
}
public void merge(int[] data, int left, int center, int right) {
// TODO Auto-generated method stub
int [] tmpArr=new int[data.length];
int mid=center+1;
//third记录中间数组的索引
int third=left;
int tmp=left;
while(left<=center&&mid<=right){

//从两个数组中取出最小的放入中间数组
if(data[left]<=data[mid]){
tmpArr[third++]=data[left++];
}else{
tmpArr[third++]=data[mid++];
}
}
//剩余部分依次放入中间数组
while(mid<=right){
tmpArr[third++]=data[mid++];
}
while(left<=center){
tmpArr[third++]=data[left++];
}
//将中间数组中的内容复制回原数组
while(tmp<=right){
data[tmp]=tmpArr[tmp++];
}
System.out.println(Arrays.toString(data));
}

}
}}}

## 8、基数排序 ##

(1)基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

(2)实例:
![请输入图片名称](http://my.csdn.net/uploads/201 ... 46.png)

(3)用java实现

{{{
import java.util.ArrayList;
import java.util.List;

public class radixSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,101,56,17,18,23,34,15,35,25,53,51};
public radixSort(){
sort(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public void sort(int[] array){

//首先确定排序的趟数;
int max=array[0];
for(int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}

int time=0;
//判断位数;
while(max>0){
max/=10;
time++;
}

//建立10个队列;
List<ArrayList> queue=new ArrayList<ArrayList>();
for(int i=0;i<10;i++){
ArrayList<Integer> queue1=new ArrayList<Integer>();
queue.add(queue1);
}

//进行time次分配和收集;
for(int i=0;i<time;i++){

//分配数组元素;
for(int j=0;j<array.length;j++){
//得到数字的第time+1位数;
int x=array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);
ArrayList<Integer> queue2=queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count=0;//元素计数器;
//收集队列元素;
for(int k=0;k<10;k++){
while(queue.get(k).size()>0){
ArrayList<Integer> queue3=queue.get(k);
array[count]=queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}

}
}}}

原文出处:http://blog.csdn.net/without08 ... 97916

【干货分享】Java那些不为人知的特殊方法

综合讨论区besy 发表了文章 • 0 个评论 • 128 次浏览 • 2015-10-14 16:01 • 来自相关话题

如果你用过反射并且执行过getDeclaredMethods方法的话,你可能会感到很吃惊。你会发现出现了很多源代码里没有的方法。如果你看一下这些方法的修饰符的话,可能会发现里面有些方法是volatile的。顺便说一句,如果在Java面试里问到“什么是volatile方法?”,你可能会吓出一身冷汗。正确的答案是没有volatile方法。但同时,getDeclaredMethods()或者getMethods()返回的这些方法,Modifier.isVolatile(method.getModifiers())的结果却是true。

immutator的一些用户遇到过这样的问题。他们发现,使用immutator(这个项目探索了Java的一些不为人知的细节)生成的Java代码使用volatile了作为方法的关键字,而这样的代码没法通过编译。结果就是这根本没法用。

这是怎么回事?syntethic和bridge方法又是什么?
可见性

当你创建一个嵌套类的时候,它的私有变量和方法对上层的类是可见的。这个在不可变嵌套式Builder模式中用到了。这是Java语言规范里已经定义好的一个行为。

{{{package synthetic;

public class SyntheticMethodTest1 {
private A aObj = new A();

public class A {
private int i;
}

private class B {
private int i = aObj.i;
}

public static void main(String[] args) {
SyntheticMethodTest1 me = new SyntheticMethodTest1();
me.aObj.i = 1;
B bObj = me.new B();
System.out.println(bObj.i);
}
}}}}

JVM是如何处理这个的?它可不知道什么是内部类或者嵌套类的。JVM对所有的类都一视同仁,它都认为是顶级类。所有类都会被编译成顶级类,而那些内部类编译完后会生成...$... class的类文件。

{{{$ ls -Fart
../ SyntheticMethodTest2$A.class MyClass.java SyntheticMethodTest4.java SyntheticMethodTest2.java
SyntheticMethodTest2.class SyntheticMethodTest3.java ./ MyClassSon.java SyntheticMethodTest1.java}}}

如果你创建一个内部类的话,它会被彻底编译成一个顶级类。

那这些私有变量又是如何被外部类访问的呢?如果它们是个顶级类的私有变量(它们的确也是),那为什么别的类还能直接访问这些变量?

javac是这样解决这个问题的,对于任何private的字段,方法或者构造函数,如果它们也被其它顶层类所使用,就会生成一个synthetic方法。这些synthetic方法是用来访问最初的私有变量/方法/构造函数的。这些方法的生成也很智能:只有确实被外部类用到了,才会生成这样的方法。

{{{package synthetic;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class SyntheticMethodTest2 {

public static class A {
private A(){}
private int x;
private void x(){};
}

public static void main(String[] args) {
A a = new A();
a.x = 2;
a.x();
System.out.println(a.x);
for (Method m : A.class.getDeclaredMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getName());
}
System.out.println("--------------------------");
for (Method m : A.class.getMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());
}
System.out.println("--------------------------");
for( Constructor<?> c : A.class.getDeclaredConstructors() ){
System.out.println(String.format("X", c.getModifiers()) + " " + c.getName());
}
}
} }}}

这些生成的方法的名字取决于具体的实现,最后叫什么也不好说。我只能说在我运行的这个平台上,上述程序的输出是这样的:

{{{2
00001008 access$1
00001008 access$2
00001008 access$3
00000002 x
--------------------------
00000111 void wait
00000011 void wait
00000011 void wait
00000001 boolean equals
00000001 String toString
00000101 int hashCode
00000111 Class getClass
00000111 void notify
00000111 void notifyAll
--------------------------
00000002 synthetic.SyntheticMethodTest2$A
00001000 synthetic.SyntheticMethodTest2$A }}}

在上面这个程序中,我们给变量x赋值,然后又调用了一个同名的方法。这会触发编译器生成对应的synthetic方法。你会看到它生成了三个方法,应该是x变量的setter和getter方法,以及x()方法对应的一个synthetic方法。这些方法并不存在于getMethods方法里返回的列表中,因为它们是synthetic方法,是不能直接被调用的。从这点来看,它们和私有方法差不多。

看一下java.lang.reflect.Modifier里面定义的常量,可以明白这些十六进制的数字代表的是什么:

{{{00001008 SYNTHETIC|STATIC
00000002 PRIVATE
00000111 NATIVE|FINAL|PUBLIC
00000011 FINAL|PUBLIC
00000001 PUBLIC
00001000 SYNTHETIC }}}

列表中有两个是构造方法。还有一个私有方法以及一个synthetic方法。存在这个私有方法是因为我们确实定义了它。而synthetic方法的出现是因为我们从外部类调用了它内部的私有成员。到目前为止,还没有出现过bridge方法。
泛型和继承

到目前为止,看起来还不错。不过我们还没有看到”volatile”方法。

看一下java.lang.reflect.Modifier的源码你会发现0x00000040这个常量被定义了两次。一次是定义成VOLATILE,还有一次是BRIDGE(后者是包内部私有的,并不对外开放)。

想出现volatile方法的话,写个简单的程序就行了:

{{{package synthetic;

import java.lang.reflect.Method;
import java.util.LinkedList;

public class SyntheticMethodTest3 {

public static class MyLink extends LinkedList<String> {
@Override
public String get(int i) {
return "";
}
}

public static void main(String[] args) {

for (Method m : MyLink.class.getDeclaredMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());
}
}
}}}}

这个链表有一个返回String的get(int)方法。先别讨论代码整不整洁的问题了。这只是段示例代码而已。整洁的代码当然也会出现同样的问题,不过越复杂的代码越难定位问题罢了。

输出的结果是这样的:

{{{00000001 String get
00001041 Object get }}}

这里有两个get方法。一个是代码里的那个,另外一个是synthetic和bridge方法。用javap反编译后会是这样的:

{{{public java.lang.String get(int);
Code:
Stack=1, Locals=2, Args_size=2
0: ldc #2; //String
2: areturn
LineNumberTable:
line 12: 0

public java.lang.Object get(int);
Code:
Stack=2, Locals=2, Args_size=2
0: aload_0
1: iload_1
2: invokevirtual #3; //Method get:(I)Ljava/lang/String;
5: areturn}}}

有趣的是,两个方法的签名是一模一样的,只有返回类型不同。这个在JVM里面是合法的,不过在Java语言里可不允许。bridge的这个方法不干别的,就只是去调用了下原始的那个方法。

为什么我们需要这个synthetic方法呢,谁会调用它?比如现在有段代码想要调用一个非MyLink类型变量的get(int)方法:

{{{List<?> a = new MyLink();
Object z = a.get(0); }}}

它不能调用返回String的方法,因为List里没这样的方法。为了解释的更清楚一点,我们重写下add方法而不是get方法:

{{{package synthetic;

import java.util.LinkedList;
import java.util.List;

public class SyntheticMethodTest4 {

public static class MyLink extends LinkedList<String> {
@Override
public boolean add(String s) {
return true;
}
}

public static void main(String[] args) {
List a = new MyLink();
a.add("");
a.add(13);
}
} }}}

我们会发现这个bridge方法

{{{public boolean add(java.lang.Object);
Code:
Stack=2, Locals=2, Args_size=2
0: aload_0
1: aload_1
2: checkcast #2; //class java/lang/String
5: invokevirtual #3; //Method add:(Ljava/lang/String;)Z
8: ireturn }}}

它不仅调用了原始的方法,它还进行了类型检查。这个检查是在运行时进行的,并不是由JVM自己来完成。正如你所想,在18行的地方会抛出一个异常:

{{{Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at synthetic.SyntheticMethodTest4$MyLink.add(SyntheticMethodTest4.java:1)
at synthetic.SyntheticMethodTest4.main(SyntheticMethodTest4.java:18) }}}

下次如果你在面试中被问到volatile方法的话,说不定面试官知道的还没你多:-)

译者注:其实作者说到最后也没讲完到底什么是volatile方法,其实volatile方法如篇首所说,是不存在的,所谓的volatile方法就是指bridge方法。由于在修饰符中volatile和bridge是同一个值,在之前版本的javap中存在一个BUG,一个bridge方法在反编译后会显示成volatile,所以存在”volatile方法”的说法。

原创文章转载请注明出处:[Java那些不为人知的特殊方法](http://it.deepinmind.com/java/ ... 5.html)

[英文原文链接](http://www.javacodegeeks.com/2 ... s.html) 查看全部
如果你用过反射并且执行过getDeclaredMethods方法的话,你可能会感到很吃惊。你会发现出现了很多源代码里没有的方法。如果你看一下这些方法的修饰符的话,可能会发现里面有些方法是volatile的。顺便说一句,如果在Java面试里问到“什么是volatile方法?”,你可能会吓出一身冷汗。正确的答案是没有volatile方法。但同时,getDeclaredMethods()或者getMethods()返回的这些方法,Modifier.isVolatile(method.getModifiers())的结果却是true。

immutator的一些用户遇到过这样的问题。他们发现,使用immutator(这个项目探索了Java的一些不为人知的细节)生成的Java代码使用volatile了作为方法的关键字,而这样的代码没法通过编译。结果就是这根本没法用。

这是怎么回事?syntethic和bridge方法又是什么?
可见性

当你创建一个嵌套类的时候,它的私有变量和方法对上层的类是可见的。这个在不可变嵌套式Builder模式中用到了。这是Java语言规范里已经定义好的一个行为。

{{{package synthetic;

public class SyntheticMethodTest1 {
private A aObj = new A();

public class A {
private int i;
}

private class B {
private int i = aObj.i;
}

public static void main(String[] args) {
SyntheticMethodTest1 me = new SyntheticMethodTest1();
me.aObj.i = 1;
B bObj = me.new B();
System.out.println(bObj.i);
}
}}}}

JVM是如何处理这个的?它可不知道什么是内部类或者嵌套类的。JVM对所有的类都一视同仁,它都认为是顶级类。所有类都会被编译成顶级类,而那些内部类编译完后会生成...$... class的类文件。

{{{$ ls -Fart
../ SyntheticMethodTest2$A.class MyClass.java SyntheticMethodTest4.java SyntheticMethodTest2.java
SyntheticMethodTest2.class SyntheticMethodTest3.java ./ MyClassSon.java SyntheticMethodTest1.java}}}

如果你创建一个内部类的话,它会被彻底编译成一个顶级类。

那这些私有变量又是如何被外部类访问的呢?如果它们是个顶级类的私有变量(它们的确也是),那为什么别的类还能直接访问这些变量?

javac是这样解决这个问题的,对于任何private的字段,方法或者构造函数,如果它们也被其它顶层类所使用,就会生成一个synthetic方法。这些synthetic方法是用来访问最初的私有变量/方法/构造函数的。这些方法的生成也很智能:只有确实被外部类用到了,才会生成这样的方法。

{{{package synthetic;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class SyntheticMethodTest2 {

public static class A {
private A(){}
private int x;
private void x(){};
}

public static void main(String[] args) {
A a = new A();
a.x = 2;
a.x();
System.out.println(a.x);
for (Method m : A.class.getDeclaredMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getName());
}
System.out.println("--------------------------");
for (Method m : A.class.getMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());
}
System.out.println("--------------------------");
for( Constructor<?> c : A.class.getDeclaredConstructors() ){
System.out.println(String.format("X", c.getModifiers()) + " " + c.getName());
}
}
} }}}

这些生成的方法的名字取决于具体的实现,最后叫什么也不好说。我只能说在我运行的这个平台上,上述程序的输出是这样的:

{{{2
00001008 access$1
00001008 access$2
00001008 access$3
00000002 x
--------------------------
00000111 void wait
00000011 void wait
00000011 void wait
00000001 boolean equals
00000001 String toString
00000101 int hashCode
00000111 Class getClass
00000111 void notify
00000111 void notifyAll
--------------------------
00000002 synthetic.SyntheticMethodTest2$A
00001000 synthetic.SyntheticMethodTest2$A }}}

在上面这个程序中,我们给变量x赋值,然后又调用了一个同名的方法。这会触发编译器生成对应的synthetic方法。你会看到它生成了三个方法,应该是x变量的setter和getter方法,以及x()方法对应的一个synthetic方法。这些方法并不存在于getMethods方法里返回的列表中,因为它们是synthetic方法,是不能直接被调用的。从这点来看,它们和私有方法差不多。

看一下java.lang.reflect.Modifier里面定义的常量,可以明白这些十六进制的数字代表的是什么:

{{{00001008 SYNTHETIC|STATIC
00000002 PRIVATE
00000111 NATIVE|FINAL|PUBLIC
00000011 FINAL|PUBLIC
00000001 PUBLIC
00001000 SYNTHETIC }}}

列表中有两个是构造方法。还有一个私有方法以及一个synthetic方法。存在这个私有方法是因为我们确实定义了它。而synthetic方法的出现是因为我们从外部类调用了它内部的私有成员。到目前为止,还没有出现过bridge方法。
泛型和继承

到目前为止,看起来还不错。不过我们还没有看到”volatile”方法。

看一下java.lang.reflect.Modifier的源码你会发现0x00000040这个常量被定义了两次。一次是定义成VOLATILE,还有一次是BRIDGE(后者是包内部私有的,并不对外开放)。

想出现volatile方法的话,写个简单的程序就行了:

{{{package synthetic;

import java.lang.reflect.Method;
import java.util.LinkedList;

public class SyntheticMethodTest3 {

public static class MyLink extends LinkedList<String> {
@Override
public String get(int i) {
return "";
}
}

public static void main(String[] args) {

for (Method m : MyLink.class.getDeclaredMethods()) {
System.out.println(String.format("X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());
}
}
}}}}

这个链表有一个返回String的get(int)方法。先别讨论代码整不整洁的问题了。这只是段示例代码而已。整洁的代码当然也会出现同样的问题,不过越复杂的代码越难定位问题罢了。

输出的结果是这样的:

{{{00000001 String get
00001041 Object get }}}

这里有两个get方法。一个是代码里的那个,另外一个是synthetic和bridge方法。用javap反编译后会是这样的:

{{{public java.lang.String get(int);
Code:
Stack=1, Locals=2, Args_size=2
0: ldc #2; //String
2: areturn
LineNumberTable:
line 12: 0

public java.lang.Object get(int);
Code:
Stack=2, Locals=2, Args_size=2
0: aload_0
1: iload_1
2: invokevirtual #3; //Method get:(I)Ljava/lang/String;
5: areturn}}}

有趣的是,两个方法的签名是一模一样的,只有返回类型不同。这个在JVM里面是合法的,不过在Java语言里可不允许。bridge的这个方法不干别的,就只是去调用了下原始的那个方法。

为什么我们需要这个synthetic方法呢,谁会调用它?比如现在有段代码想要调用一个非MyLink类型变量的get(int)方法:

{{{List<?> a = new MyLink();
Object z = a.get(0); }}}

它不能调用返回String的方法,因为List里没这样的方法。为了解释的更清楚一点,我们重写下add方法而不是get方法:

{{{package synthetic;

import java.util.LinkedList;
import java.util.List;

public class SyntheticMethodTest4 {

public static class MyLink extends LinkedList<String> {
@Override
public boolean add(String s) {
return true;
}
}

public static void main(String[] args) {
List a = new MyLink();
a.add("");
a.add(13);
}
} }}}

我们会发现这个bridge方法

{{{public boolean add(java.lang.Object);
Code:
Stack=2, Locals=2, Args_size=2
0: aload_0
1: aload_1
2: checkcast #2; //class java/lang/String
5: invokevirtual #3; //Method add:(Ljava/lang/String;)Z
8: ireturn }}}

它不仅调用了原始的方法,它还进行了类型检查。这个检查是在运行时进行的,并不是由JVM自己来完成。正如你所想,在18行的地方会抛出一个异常:

{{{Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at synthetic.SyntheticMethodTest4$MyLink.add(SyntheticMethodTest4.java:1)
at synthetic.SyntheticMethodTest4.main(SyntheticMethodTest4.java:18) }}}

下次如果你在面试中被问到volatile方法的话,说不定面试官知道的还没你多:-)

译者注:其实作者说到最后也没讲完到底什么是volatile方法,其实volatile方法如篇首所说,是不存在的,所谓的volatile方法就是指bridge方法。由于在修饰符中volatile和bridge是同一个值,在之前版本的javap中存在一个BUG,一个bridge方法在反编译后会显示成volatile,所以存在”volatile方法”的说法。

原创文章转载请注明出处:[Java那些不为人知的特殊方法](http://it.deepinmind.com/java/ ... 5.html)

[英文原文链接](http://www.javacodegeeks.com/2 ... s.html)

为什么下载完了myeclipse后出现一个me

下载|安装|配置|更新besy 回复了问题 • 2 人关注 • 1 个回复 • 46 次浏览 • 2015-10-12 09:26 • 来自相关话题

SmileMiner:国人李海峰开发的开源Java机器学习库

综合讨论区besy 发表了文章 • 0 个评论 • 195 次浏览 • 2015-10-10 09:33 • 来自相关话题

**SmileMiner**是一个汇集了各种机器学习算法的纯Java函数库,它是自包含的,仅仅需要Java标准库。主要部件为:Smile,-Math,-Data,-Graph,-Interpolation,-NLP。不可多得的Java机器学习库,其文档和示例都挺赞!

链接:[https://github.com/haifengl/smile](https://github.com/haifengl/smile)

![请输入图片名称](http://img.blog.csdn.net/20151010083309813) 查看全部
**SmileMiner**是一个汇集了各种机器学习算法的纯Java函数库,它是自包含的,仅仅需要Java标准库。主要部件为:Smile,-Math,-Data,-Graph,-Interpolation,-NLP。不可多得的Java机器学习库,其文档和示例都挺赞!

链接:[https://github.com/haifengl/smile](https://github.com/haifengl/smile)

![请输入图片名称](http://img.blog.csdn.net/20151010083309813)

哪个是解压版的myeclipse???

下载|安装|配置|更新dcxmaozi 回复了问题 • 2 人关注 • 2 个回复 • 37 次浏览 • 2015-10-08 17:55 • 来自相关话题