黑马程序员 Java高新技术-jdk1.5新特性和反射基础

一、JDK1.5 中简单的新特性

静态导入;例如:

package com.staticimport.demo;
import static java.lang.Math.max;
import static java.lang.Math.abs;
public class StaticImport {
	/**
	 * @param args
	 * 静态导包。
	 */
		public static void main(String[] args) {
			//使用了静态导包之后可以直接调用方法
			System.out.println(max(26.3,32.5));
			System.out.println(abs(3-10));
		}
}

可变参数

可变参数特点:

只能出现在参数列表最后

“… ”位于变量类型和变量名之间,前后有无空格都可以

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

例:

package com.enable.demo;
public class EnableParameters {
		public static void main(String[] args) {
			System.out.println(enableChange(10, 2,3));
			System.out.println(enableChange(10, 2,3,5));
			System.out.println(enableChange(10, 2,3,5,10));
		}
			public static int enableChange(int x ,int... args){
			int count = 0 ;
			for (int i = 0; i < args.length; i++) {
				count += args[i];
			}
			return count ;
		}
}

语法:for(type(变量) : 变量名)

自动装箱与拆箱

享元模式:有很多个相同属性的小的对象封装成一个对象,而其他不同的属性作为方法的参数,这些叫外部状态,形同的属性称之为内部状态。

例如:

Integer iObj = 36 ;
		 Integer iObj1 = 36 ;
		 System.out.println(iObj == iObj1); //true
		 Integer iObj2 = 136 ;
		 Integer iObj3 = 136 ;
		 System.out.println(iOb2 == iObj3); //false

二、java5的枚举




2、枚举的实现       

public class EmumDemo {
	public static void main(String[] args) {
		/*
		WeekDay1 weekDay = WeekDay1.MON;
		System.out.println(weekDay);
		System.out.println(weekDay.nextDay());
		*/
		WeekDay weekDay = WeekDay.THI ;
		System.out.println(weekDay);
		System.out.println(weekDay.name());
		System.out.println(weekDay.ordinal());
		System.out.println(weekDay.valueOf("SUN").toString());
	}
	//定义一个枚举类
	public enum WeekDay{
		SUN,MON,TUE,WED,THI,SAT;
	}
}

3、 为枚举定义构造方法(带参数的构造方法)

定义的所有方法都必须在元素列表之后 ,且元素列表必须有分好”;”即结束符号。

         如果枚举中只有一个元素可以用,那么这个枚举可以写成一个单例。

下面代码是一个带有有参构造方法和抽象方法的枚举类。描述了一组交通灯。


public enum TrifficLamp {
	RED(20) {
		// 覆写类中抽象方法
		public TrifficLamp netLamp() {
			return BLUE;
		}
	},
	BLUE(45) {
		public TrifficLamp netLamp() {
			return YELLOW;
		}
	},
	YELLOW(5) {
		public TrifficLamp netLamp() {
			return RED;
		}
	};
	public abstract TrifficLamp netLamp();
	private int time;
	private TrifficLamp(int time) {
		this.time = time;
}
}

三、反射的深入讲解

1、反射的基石—>Class类

         Java程序中的各个类属于同一类事物,描述这类事物的java类名就是Class

                   Person->人

                   Java类->Class

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

如何的到各个字节码对应的实例对象(Class类型)

(1)      类名.class,例如,System.calss;

(2)      对象.getClass(),例如,new Date().getClass();

(3)      Class.forName(“类名”)例如”Class.forName(“java.util.Date”);

例:用上面的三种方式获取对象的clss字节码对象

public class GetClassFile {
	public static void main(String[] args)throws Exception {
		String str = "abc";
		 Class clazz1 = str.getClass();
		 Class clazz2 = String.class;
		 Class clazz3 = Class.forName("java.lang.String");
		 System.out.println(clazz1 == clazz2);
		 System.out.println(clazz1 == clazz3);
		//isPrimitive()判断是否是一个基本类型的字节码
		 System.out.println(clazz1.isPrimitive());
	}
}

2、反射的概念

         反射就是把一个java类中的各个成分(如:成员,方法等)映射成相应的java类。

例:反射一个类中的构造方法,并用其创建并实例化一个新对象

import java.lang.reflect.Constructor;
public class ReflectConstructorDemo {
	public static void main(String[] args) throws Exception {
		String content = "StringBuffer为构造器参数的String对象";
		// 获取String字节码对象
		Class clazz = Class.forName("java.lang.String");
		// 获取String的带参构造方法,参数类型是:StringBuffer
		Constructor<String> constructor = 
				clazz.getConstructor(StringBuffer.class);
		// 创建String对象,使用构造器参数为StringBuffer
		String str = 
constructor.newInstance(new StringBuffer(content));
		System.out.println(str);
	}
}

例:反射一个类中成员,并打印其值

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectConstructorDemo {
	public static void main(String[] args) throws Exception {
		ReflectPoint rp = new ReflectPoint(20, 10);
		//获取ReflectPoint字节码对象
		Class clazz1 = Class.forName("com.reflect.demo.ReflectPoint");
		//获取成员y
		Field fieldY = clazz1.getField("y");
		System.out.println(fieldY.get(rp));
		//由于x的访问权限修饰符为private,所以要使用强制反射
		Field fieldX = clazz1.getDeclaredField("x");
		//强制访问
		fieldX.setAccessible(true);
		System.out.println(fieldX.get(rp)); 
	}
}

ReflectPoint.java类略。

例:反射成员的综合应用,修改成员的值

private static void changeValue(Object rp)throws Exception {
		//获取字节码对象的所有成员,存入到数组fields
		Field[] fields = rp.getClass().getFields();
		//迭代出每一个成员
		for(Field field : fields){
			//如果成员的类型为String,执行替换操作
			if(field.getType() == 
				Class.forName("java.lang.String")){
				String oldValue = (String) field.get(rp);
				String newValue = oldValue.replace('b', 'c');
				field.set(rp, newValue);
			}
		}
	}

执行上述代码时候,需要在ReflectPoint中加入一个String类型的成员,成员名您随意。

例:通过反射调用类中的成员方法

<pre name="code" class="java">public static void reflectMethod(String str1)throws Exception {
		//获取Str1的字节码对象,并获取方法,并赋值给methodCharAt
		Method methodCharAt = 
			str1.getClass().getMethod("charAt", int.class);
		//调用str1对象的charAt方法,传入参数2;等价于str1.charAt(2)
		System.out.println(methodCharAt.invoke(str1, 2));
		//按照jdk1.4的语法调用str1对象的charAt方法,传入参数1;等价于str1.charAt(1)
		System.out.println(
methodCharAt.invoke(str1, new Object[]{1}));
}

 

上述代码在调用的时候需要传入一个String类型的对象,值随意。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值