您的位置:首页 > 职场人生

黑马程序员 Java高新技术1

2013-07-29 17:06 423 查看
 ------- android培训、java培训、期待与您交流! ----------

 

可变参数的特点:

1.只能出现在参数列表的最后。

2."..."位于变量类型和变量名之间,前后无空格都可以。

3.调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。

public class VarableParameter {

public static void main(String[] args) {
System.out.println(add(2,3));
System.out.println(add(2,3,4));
}

public static int add(int x,int... args){
int sum=x;
for(int i=0;i<args.length;i++){
sum+=args[i];
}
return sum;
}

}

增强for循环:

格式:for(type 变量名:集合变量名){...}

注意:迭代变量必须在()中定义。集合变量可以是数组或实现了Iterable接口的集合类。

还以上面例子来写:

public class VarableParameter {

public static void main(String[] args) {
System.out.println(add(2,3));
System.out.println(add(2,3,4));
}

public static int add(int x,int... args){
int sum=0;
for(int arg:args){
sum+=arg;
}
return sum;
}

}

享元模式(flyweight):有很多小的对象,他们有很多属性相同把他们变成一个对象,那些不同的属性把他们变成方法的参数成为外部状态,那些相同的成为内部状态。

Integer对象在-128-127之间会缓存在池中

class AutoBox {

public static void main(String[] args) {
Integer iObj=3;
System.out.println(iObj+3);

Integer i1=13;
Integer i2=13;
Integer i4=128;
Integer i5=128;

System.out.println(i1==i2);
System.out.println(i4==i5);
}
}

结果:15  true false

枚举:

枚举就是要让某个类型的变量的取之只能为若干个固定值中的一个,否则编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

如何实现枚举:

1.私有构造函数。

2.每个元素分别用一个公有的静态成员变量表示。

3.可以有若干公有方法或抽象方法。

public abstract class WeekDay1 {
public final static WeekDay1 SUN = new WeekDay1(){
public WeekDay1 nextDay() {
return MON;
}
};
public final static WeekDay1 MON = new WeekDay1(){
public WeekDay1 nextDay() {
return SUN;
}
};

private WeekDay1(){}
public abstract WeekDay1 nextDay();
public String toString(){
return this == SUN?"SUN":"MON";
}
}
public class EnumTest {
public static void main(String[] args) {

//WeekDay1 weekDay = WeekDay1.MON;
//System.out.print(weekDay.nextDay());

WeekDay weekDay2 = WeekDay.FRI;
//System.out.println(weekDay2);
System.out.println(weekDay2.name());
System.out.println(weekDay2.ordinal());   //获取FRI在枚举中的位置
System.out.println(WeekDay2.valueOf("SUN"));
System.out.println(WeekDay.values().length);   //获取枚举内的所有元素并返回数组
}
//带有构造方法的枚举
public enum WeekDay{
SUN(1),MON(),TUE,WED,THI,FRI,SAT;
private WeekDay(){System.out.println("first");}
private WeekDay(int i){	System.out.println("second");}
}
}

枚举相当于一个类,其中可以定义构造方法、成员变量、普通方法和抽象方法。

枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后面要有分号与其他成员分隔.把枚举中的成员方法或变量等放在枚举元素的前面,编译器会报告错误。

构造方法必须定义成私有。

枚举的元素是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。

枚举只有一个成员时,就可以作为一种单例的实现方式。

public class EnumTest2 {

public static void main(String[] args) {

}

public enum Trafficlamp{
RED(30){
public Trafficlamp nextTra() {
return GREEN;
}
},
GREEN(45){
public Trafficlamp nextTra() {
return YELLOW;
}
},
YELLOW(5){
public Trafficlamp nextTra() {
return RED;
}
};
public abstract Trafficlamp nextTra();
private int time;
private Trafficlamp(int time){this.time=time;}
}
}


反射的基石--Class类:

一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以他们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型。

如何得到字节吗对应的类:

1.类名.class,例如:System.class

2.对象.getClass().例如:new String().getClass()
3.Class.forName("类名"),例如:Class.forName("java.util.Date")

九个预定义Class实例对象

boolean, byte, char, short, int, long, float,double, void

通过字节码.isPrimitive() 方法来判断是否是基本数据类型。

基本数据类型包装类的常量TYPE代表所包装的基本数据类型字节码。例如:int.class==Integer.TYPE的结果为true。

数组类型的Class实例通过 字节码.isArray() 来判断是否为数组。

反射:反射就是把Java类中的各种成分映射成相应得Java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等信息用一个个的Java类来表示。表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的实例对象来表示,他们是:Field,Method,Contructor,Package等等。

 Constructor类代表某个类中的一个构造方法

得到某个类所有的构造方法:

例: Constructor[] constructors = Class.forName("java.lang.String").getConstructors()。

得到某一个构造方法:

例:Constructor[] constructors = Class.forName("java.lang.String").getConstructors(StringBuffer.class).

创建实例对象:

通常方式:String str = new String(new StringBuffer("asd")).

反射方式: String s = (String)constructor.newInstance(new StringBuffer("abc"))。

Class newInstance()方法

该方法是得到默认的构造方法,然后用构造方法创建实例对象。

import java.lang.reflect.Constructor;

public class ConstructorDemo {
public static void main(String[] args) throws Exception{

Constructor<String> constructor = String.class.getConstructor(StringBuffer.class);
String str = constructor.newInstance( new StringBuffer("abc"));
System. out.print(str.charAt(2));
}
}


Fisld类:

代表某个类中的一个成员变量。

如何获取对象的成员变量对象:

 Field filedX = 对象.getClass().getField("变量名")。

这里,如果成员变量为私有的,那么需要用以下方法:

 Field filedX = 对象.getClass().getDeclaredField("变量名")。

不过这里还不可以对私有变量进行操作,需要用到setAccessible(true)方法,暴力获取。

import java.lang.reflect.Field;
class ReflectPoint{
private int x;
public int y;
public ReflectPoint( int x, int y) {
super();
this. x = x;
this. y = y;
}
}
class FieldDemo{
public static void main(String[] args) throws Exception{
ReflectPointt rp = new ReflectPoint(3,5);
Field fieldY = ReflectPoint. class.getField( "y");
System. out.println(fieldY);
System. out.println(fieldY.get(rp));

Field fieldX = WhyNot. class.getDeclaredField( "x");
Syste
4000
m. out.println(fieldX);//5
fieldX.setAccessible( true); //设置变量x为可访问
System. out.println(fieldX.get(rp)); //3
}
}

更改变量的值:

import java.lang.reflect.Field;
/*
把字符串中的'b'换成'a'.
*/
class TestString{
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
}
public class FIeldTest {
public static void main(String[] args) throws Exception {
TestString ts = new TestString();
//获取所有变量,返回Field数组
Field[] fields = ts.getClass().getFields();
//高级for循环遍历
for(Field field : fields){
//判断变量类型是否为String
if(field.getType() == String. class){
//向下转型为String类型
String oldValue = (String)field.get(ts);
//调用String类中的replace方法
String newValue = oldValue.replace( 'b', 'a');
//把修改后的字符串重新赋值给 ts对象的变量
field.set(ts, newValue);
System. out.println(field.get(ts));
}
}
}
}

Method类代表某个类中的成员方法。

得到类中的某一个方法:

Method charAt = Class.forName("java.lang.String").getMethod("charaAt",int.class).

调用方法例:

charAt.invoke(str , 1)。

这里要说明一点:如果传递给Method对象的invoke()方法的对象参数是null , 说明该Method方法是一个静态方法。

import java.lang.reflect.Method;

public class MethodDemo {
public static void main(String[] args) throws Exception{
String str = "abc";
Method md = String. class.getMethod( "charAt", int. class);

System. out.println(md.invoke(str, 1));
System. out.println(md.invoke(str, new Object[]{2}));
}

}

反射中main方法(静态)的调用:

import java.lang.reflect.Method;
public class MethodTest {

public static void main(String[] args) throws Exception{
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod( "main", String[]. class);
//两种方式来调用静态main方法
mainMethod.invoke( null, new Object[]{ new String[]{"aa","bb" ,"cc" }});
//mainMethod.invoke(null, (Object)new String[]{"aa","bb","cc"});
}
}

class TestArguments{
public static void main(String[] args){
for(String arg : args){
System. out.println(arg);
}
}
}

数组的反射:

1.具有相同维数和元素类型的数组属于同一个Class类型 , 具有相同的Class实例对象。

2.代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Class。

3.基本类型的一维数组可以被当成Object类型使用 , 不能当作Object[]类型使用 ; 例如 : int[]可以是Object , 但不能是Object[] ; 非基本类型的一维数组 ,既可以当作Object类型使用 , 又可以当作Object[]类型使用。

4.Arrays.asList()方法处理int[]和String[]时的差异:int[]被当成一个Object元素存进集合 , String[]被当成一个Object[]数组 , 数组的元素被拆开后存进集合。

部分代码:

int [] a1=new int[3];
int [] a2=new int[4];
int [][] a3=new int[2][3];
String [] a4=new String[3];
System.out.println(a1.getClass()==a2.getClass());
System.out.println(a1.getClass()==a4.getClass());
System.out.println(a1.getClass()==a3.getClass());
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());

结果:true  false  false  [I  java.lang.Object   java.lang.Object

例2:

import java.lang.reflect.Array;
public class Test {
public static void main(String[] args) {
String[] strs = new String[]{ "a", "b"};
String str = "xy";

printObject(strs);
printObject(str);
}
public static void printObject(Object obj){
Class c = obj.getClass();
System. out.println(c.getName());
if(c.isArray()){
int len = Array. getLength(obj);
for( int x = 0; x < len; x++){
System. out.println(Array. get(obj, x)); //用Array类中的get()方法遍历出数组中的元素
}
}
else
System. out.println(obj);
}
}

关于集合中HashSet的一点注意:当一个对象被存储进HashSet集合中已后,就不能修改这个对象中的那些参与运算哈希值的字段了,否则,对象修改后的哈希值与最初的HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

内省(IntroSpector)JavaBean:

JavaBean是一种特殊的Java类,主要用于传递信息,这种Java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。

规则:去掉get、set后的字母,例如,一个类有方法getAge( )和setAge( ) , 那么bean的属性为age,而不是成员变量,因为成员变量是private看不见的。

获得属性名的规则:如果属性名的第二个字母是小写,则把第一个字母小写。例如,gettime—>time,setTime—>time,getCPU—>CPU。

 

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