您的位置:首页 > 编程语言 > Java开发

JAVA高新技术学习<一>

2012-09-18 10:41 477 查看
(jdk1.5新特性:枚举,注解,泛型)

高新技术知识点:

1.可变参数和增强for循环

/**可变参数的特点:
*...只能出现在参数列表最后面
*位于变量类型和变量名之间,前后无空格都可以
*调用可变参数方法时,编译器为该可变参数创建隐含数组,
*注意:它只为可变参数创建数组,上面的intx不在可变参数中,所以x不在可变参数中
*把intx删掉,则所有参数均纳入数组中
*在方法体中以数组形式访问可变参数。
*/

packageItcast.com;

[code]//importstaticjava.lang.Math.max;//必须是静态导入
//importstaticjava.lang.Math.abs;//要加static


publicclasszhang01

{

publicstaticvoidmain(String[]args)

{

add(3,5,6);

}

publicstaticvoidadd(int...args)//可变参数


{

//这里sum=0是错的,一开始是第一个值

/*

for(inti=0;i<args.length;i++)//这里犯过低级错误for条件体之间是用;隔开

{

sum+=args[i];

}

returnsum;

*/

//加强for循环(迭代取值)

//格式:for(type变量名:集合变量的名字){}

intsum=0;

for(intarg:args)//自定义变量arg,用arg去迭代集合agrs,用arg逐一去取args里的元素

{

System.out.println(arg);

sum+=arg;

}

System.out.println(sum);

}


}

//overload重载

//override重写

[/code]

2.自动拆装箱和享元设计模式

/*享元模式(设计模式)
*有很多个小的对象,他们有很多属性相同,所以把他们变成一个对象,
*那些不同的属性把他们变成方法的参数。
*将基本数据类型数字装箱时,如果在其在一个字节之内(-128到127)
*由于位于常用区域不会改变,所以将其缓存起来,下次可直接拿来用
*没必要一个数字对应多个对象公用即可*
*/
packageItcast.com;

publicclassAutoBox
{
publicstaticvoidmain(String[]args)
{
Integeriobj=125;
Integerjobj=125;
System.out.println(iobj==jobj);
/**
*
*/
}

}


3.枚举

3.1用普通类模拟实现枚举功能

packageItcast.com;

[code]publicabstractclassWeekDay1
{

privateWeekDay1(){}//私有的构造方法



/*定义外部类的抽象方法

*/

publicabstractWeekDay1nextDay();


//每个元素分别用一个公有的静态成员表示


/*现在想要在这个抽象类WeekDay1里面创建枚举类型的对象,就不能直接用new了,因为是抽象类不可以

*只能用这个类的子类来创建对象,但这个子类必须要复写父类的所有抽象方法才可以

*把本来大量的ifelse语句转为了一个个独立的类(内部类)

*/

publicfinalstaticWeekDay1SUN=newWeekDay1(){//用匿名内部类去复写抽象方法

publicWeekDay1nextDay()

{

returnMON;

}

};

//通过匿名内部类复写父类抽象方法后,成功创建了抽象类的对象

publicfinalstaticWeekDay1MON=newWeekDay1()

{

publicWeekDay1nextDay()

{

returnSUN;

}

};

/*publicWeekDaynextDay()

{

if(this==SUN)

{

returnMON;

}

else

{

returnSUN;

}

}*/



//对象创建完成,把对象的返回值类型转成字符串,便于打印结果

publicStringtoString()

{

returnthis==SUN?"SUN":"MON";

}


}

[/code]

3.2定义一个正规的枚举用enum关键字实现,演示规范的枚举定义

packageItcast.com;

[code]
publicclassEnumTest//枚举

/*定义类型,让这些类型的变量指向的指是指定的值

*演示用普通类实现枚举的方法,如下

*/

{

publicstaticvoidmain(String[]args)

{

//自定义枚举

WeekDay1weekDay=WeekDay1.MON;

System.out.println(weekDay.nextDay());


//利用专业枚举演示:

WeekDayweekDay2=WeekDay.FRI;

System.out.println(weekDay2.name());

//返回指定对象在枚举元素中的位置,从0开始计数

System.out.println(weekDay2.ordinal());

//把别人传过来的字符串变成一个实际的星期对象

System.out.println(weekDay2.valueOf("SUN"));

//返回一个数组,把枚举里面的元素都装进数组,还可以对数组

//进行操作

System.out.println(weekDay2.values().length);

System.out.println(TrafficLamp.GREEN.time);

}

/*

*定义一个正规的枚举用enum关键字实现

*/

//可以给枚举自定义

publicenumWeekDay

{

//静态的成员变量,执行后都会初始化

//枚举的元素必须写在所有成员最前面,注意!!

SUN(1),MON(),TUE(1),WED,THI,FRI,SAT;

/*如下面所示,给出两个构造函数,一个没参数,一个带int类型的参数

*那么初始化的时候到底构造谁呢?

*在上面的元素列表中元素后面加(),如果里面有int值,则调用

*带参数的构造方法传入相应参数来构造对应的元素,没值则调用空参数的那个来构造

*对应的元素

*即实现元素的差别化构造

*/

//构造方法必须是私有的,而且必须位于元素列表之后

privateWeekDay()

{

System.out.println("first");

}

privateWeekDay(intday)

{

System.out.println("second");

}

}

//定义一个交通灯枚举类,他有三个元素:红绿黄

publicenumTrafficLamp

{

RED(30)

{

publicTrafficLampnextLamp()

{

returnGREEN;

}

},

GREEN(45)

{

publicTrafficLampnextLamp()

{

returnYELLOW;

}

},

YELLOW(5)

{

publicTrafficLampnextLamp()

{

returnRED;

}

};

//每个元素通过内部类都复写了父类的抽象方法得以建立对象

//很重要的一点,枚举元素是写在所有成员(变量、函数)的最前面的。

publicabstractTrafficLampnextLamp();

//成员变量time,通过构造函数可以给每个元素赋予相应的time值

privateinttime;

//这样子类就会调用父类有参的构造方法

privateTrafficLamp(inttime)

{

this.time=time;

}



}



}

[/code]

4.反射

/**
*反射的基石Class类
*用于描述java程序中用到的各个java类,他们的共性就是
*他们都是java中的类,所以可以用Class类来描述
*Class类不能直接用new来创建对象,他是一堆类的字节码
*定义方法
*Classclas1=Date.class//得到相应类的字节码
*拥有的方法:
*p1.getClass():得到对象所属的那份字节码
*类的静态方法forName:
*返回字节码文件:1.已加载到虚拟机中的,直接返回该字节码
*2.虚拟机里没有,用类加载器加载并缓存到虚拟机再返回该字节码
*Class.forName("java.lang.String")
*得到各个字节码对应的实例对象(Class类型)
*1类名.class
*2对象.class
*3Class.forName("类名")
*八个基本数据类型加void预定义了Class实例对象
*@authorshantui
*反射就是把java类中的各种成分映射成相应的java类
*反射的constructor类:得到某个类所有的构造方法
*/

先自定义一个反射点

packageItcast.com;

[code]
publicclassReflactPoint

{

/*

privateintx;

publicinty;

ReflactPoint(intx,inty)

{

this.x=x;

this.y=y;

}

*/


publicStringstr1="ball";

publicStringstr2="basketball";

publicStringstr3="fbbtball";

//反射点


publicStringtoString()

{

returnstr1+";"+str2+";"+str3;

}



//选中x,然后alt+shif+s:快速产生构造方法



}

[/code]

4.1对构造方法、自定义方法、数组的反射演示

packageItcast.com;

[code]
//importjava.lang.reflect.Constructor;

importjava.lang.reflect.Array;

importjava.lang.reflect.Field;

importjava.lang.reflect.Method;

importjava.util.Arrays;

publicclassreflect

{

publicstaticvoidmain(String[]args)throwsException

{

Stringstr1="abc";

/**

Classcls1=str1.getClass();

//Classcls2=String.class;

//Classcls3=Class.forName("java.lang.String");

//System.out.println(cls1==cls2);

//System.out.println(cls3==cls2);

//验证是不是个基本数据类型的字节码

//结果是否,因为他是个类

//System.out.println(cls1.isPrimitive());

//int是基本数据类型

//System.out.println(int.class.isPrimitive());

//问:int[]这个类型是不是数组类型

//结果:是这样判断的

//System.out.println(int[].class.isArray());


//constructor构造器类型,方法使用:



//得到String类中指定构造方法,哪个呢(有很多个构造方法而且无序)?

//我只想得到构造方法中:接受参数为两个,分别是StringBuffer类型,int类型

//只想得到这种,如何得到,如下:

//Constructorconstructor1=String.class.getConstructor(StringBuffer.class,int.class);


//用反射实现此效果:newString(newStringBuffer("abc")),就是给String的构造函数传入的是一个abc,这个abc是个StringBuffer类型,以此完成new一个String

//重新对StringBuffer进行自定义的构造

//编译期不执行等号右边的运算,所以不知道constructor是谁的构造方法,返回的是谁的,所以要指明

//不指明编译期通不过的

//Constructorconstructor2=String.class.getConstructor(StringBuffer.class);

//得到构造方法后,怎么用?:有一个newInstanc方法:构造一个实例对象。

//Stringstr2=(String)constructor2.newInstance(newStringBuffer("abc"));

//System.out.println(str2.charAt(2));

//创建一个对象的一般方法class->constructor-->newobject

//为简化过程,用到了newInstance:创建一个实例对象:Class.newInstance


//给反射点传入两个值

*

*/

ReflactPointpt1=newReflactPoint();

/**得到一个类身上的某个字段

Fied类代表某个类中的一个成员变量,即成员变量类

filedy的值不是5,因为filedy不是对象身上的变量,而是类上的,要用它去取x和Y

他把类上的指定的成员变量封装起来,成为类里的一个变量,可用他去取值

Fieldfieldy=pt1.getClass().getField("y");

System.out.println(fieldy.get(pt1));

由于x私有了,要想得到x,需要用getDeclaredField("x")

Fieldfieldx=pt1.getClass().getDeclaredField("x");

把私有的x进行暴力反射

fieldx.setAccessible(true);

System.out.println(fieldx.get(pt1));

*/

changeStingValue(pt1);

System.out.println(pt1);

/**

通过反射调用Sting类型的CharAt()方法

得到String类文件中的指定方法,即名字为charat,接受的数据类型为int类型的那个重载形式

这里的名字一定要是系统存在的函数名,而且不要写错,比如首字母是小写的。

*/

MethodmethodCharAt=String.class.getMethod("charAt",int.class);

/**

invok:调用,他是方法身上的调用,即方法的开启标志和信号

invok格式:invok(要用charAt的变量名称,你要charAt第几个?)

如果出现这样的格式:invok(,x),说明该Method方法,这是个静态方法

*/

System.out.println(methodCharAt.invoke(str1,1));


/**

*TestArguments.main(newString[]{"abc","ddd"});

如果要启用的TestArguments这个类是客户输入的,我们不知道,则上面的方法不可行了

为什么要用反射调用main,假如TestArguments中,每个args[i]都是个类名,我们不知道客户想运行哪个类的主函数

这是就要用到反射,给我你想运行的类名,我反射一下就可以执行其主函数

*/


/**

*这里调出软件的runas对话框,把此主函数入口中要传入的(x)=Arguments

*这样这个主函数就会被传入一个类类型的变量,相当于客户输入了一个类,

*让本类来运行他的主函数*

*/

StringstartingClassName=args[0];

MethodmainMethod=Class.forName(startingClassName).getMethod("main",String[].class);


mainMethod.invoke(null,(Object)newString[]{"abc","123","sss"});

/*

*数组反射演示:

*/

int[]a1=newint[]{1,2,3};

int[]a2=newint[4];

int[][]a3=newint[1][2];

String[]a4=newString[]{"111","2222","3"};

System.out.println(a1.getClass()==a2.getClass());

System.out.println(a1.getClass().getName());//“[I”代表:整数数组

System.out.println(a1.getClass().getSuperclass().getName());//数组父类名


/*

*基本数据类型都不是Object类型

*所以Object[]aobj1=a1是错的,int不是Object类型,int[]是

*/

Object[]aobj4=a4;//String是Object类型

Object[]aobj3=a3;

/**

object数组内装了一个abject类型的数组,即二维数组。

aslist方法可以把字符串数组的元素转成List集合的形式,但它只接受Object类型的数组

,但int类型数组不符合,所以只把a1当成一个单纯Object数处理。

*/

System.out.println(Arrays.asList(a1));

System.out.println(Arrays.asList(a4));

//数组反射演示:

Objectobj=null;

printObject(a4);


}


privatestaticvoidprintObject(Objectobj)

{

//TODOAuto-generatedmethodstub

Classclasz=obj.getClass();

if(clasz.isArray())

{

intlen=Array.getLength(obj);

for(inti=0;i<len;i++)

{

System.out.print(Array.get(obj,i)+"");

}

}

else

{

System.out.println(obj);

}

}






//把指定成员变量的值按照指定的规则替代(把b全换成a)

privatestaticvoidchangeStingValue(Objectobj)throwsException

{

//TODOAuto-generatedmethodstub

Field[]fields=obj.getClass().getFields();

for(Fieldfield:fields)

{

//字节码的比较用等号,因为都只有一份

//if(field.getType().equals(String.class))

if(field.getType()==String.class);

{

Stringoldvalue=(String)field.get(obj);

StringnewValue=oldvalue.replace('b','a');

field.set(obj,newValue);


}

}


}

}


classTestArguments//等待客户输入此类

{

publicstaticvoidmain(String[]args)

{

for(Stringarg:args)

{

System.out.println(arg);

}


}

}

[/code]

4.2用对类的反射实现客户给我什么类,我就运行什么类的效果

/*获取类的方法2:类加载器
*配置文件都放在classpath指定的目录下。
*获取类的方法1:通过配置文件:
*通过集合框架的形式,传入指定的集合类型,可将下面的
*集合类定义成用户传入的类,这里就需要传入一个配置文件“config.properties”
*在里面预先写入想传入的是哪个集合类

packageItcast.com;

[code]importjava.io.FileInputStream;
importjava.io.InputStream;

importjava.util.Collection;

importjava.util.Properties;

publicclassReflectTest2

{

publicstaticvoidmain(String[]args)throwsException

{


//获得ReflectTest2类的类加载器后到classpath指定的目录中去加载指定的类,

ReflectTest2.class.getClassLoader().getResourceAsStream("E:/lsk/studyTest//config.properties");


//读取配置文件

InputStreamips=newFileInputStream("config.properties");

//利用properties类加载读取的配置文件中的信息

Propertiesprops=newProperties();

props.load(ips);

ips.close();

//按照配置文件中的类名,找到其值(类的类型),即由其key找到其value(集合类型),赋给className

StringclassName=props.getProperty("className");

//按照类名(key=className)找到对应类类型(value)后新构造一个collections

Collectioncollections=(Collection)Class.forName(className).newInstance();


//Collectioncollections=newHashSet();

personp1=newperson(5,5);

personp2=newperson(5,5);

personp3=newperson(3,3);

collections.add(p1);

collections.add(p2);

collections.add(p3);

collections.add(p1);

System.out.println(collections.size());

}

}

classperson

{

intx=0,y=0;

person(intx,inty)

{

this.x=x;

this.y=y;

}


}


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: