黑马程序员--Java高新技术(1)

------- android培训java培训、期待与您交流! ----------

1.设置可变参数的函数:

public static int add(int x,int...args){
		int sum = 0;
		for(int arg : args){//增强的for循环
			sum += arg;
		}
		return sum;
	}


2.基本数据类型的自动装箱和拆箱,


基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。

一般我们要创建一个类的对象的时候,我们会这样:Class a = new Class(parameter);

当我们创建一个Integer对象时,却可以这样:Integer i = 100; (注意:不是 int i = 100; )

实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = new Integer(100); 此即基本数据类型的自动装箱功能。

自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用

这里面其实使用了一个设计模式:享元模式,具体请参看这篇文章:


3.枚举


特点:构造函数私有化,所以如果有一个枚举,可以作为特殊的单例

public enum TranfficLamp{
		RED (30){
			@Override
			public TranfficLamp nextLamp() {
				return GREEN;
			}
		},GREEN(45) {
			@Override
			public TranfficLamp nextLamp() {
				// TODO Auto-generated method stub
				return YELLOW;
			}
		},YELLOW(5) {
			@Override
			public TranfficLamp nextLamp() {
				// TODO Auto-generated method stub
				return RED;
			}
		};
		public abstract TranfficLamp nextLamp();
		private int time;
		private TranfficLamp(int time){
			this.time = time;
		}
	}
使用方式:

	TranfficLamp t1 = TranfficLamp.RED;
		TranfficLamp t2 = t1.nextLamp();

4.Java反射机制:

反射就是把Java类中的各个成分映射成相应的Java类;

Class(字节码对象)的3中获取方式:

Objexct.getClass();

类名.Class;

Class.forName();

public boolean isPrimitive()判定指定的 Class 对象是否表示一个基本类型。 
public boolean isArray()判定此 Class 对象是否表示一个数组类。

4.1构造函数的反射

Class cl = Person.class;
		Constructor cst = cl.getConstructor(String.class,String.class,int.class);
		Person p = (Person) cst.newInstance("张三","boy",15);//产生新对象
		System.out.println(p.toString());
关于Person类,定义如下:

public class Person {
	private String name;
	private String sex;
	private int age;

	public Person(String name, String sex,int age) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	public void setPerson(String name, String sex,int age) {
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setages(int[] ages){
		this.age = ages[0];
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}
}

4.2 成员变量的反射

	Person person = new Person("张三","sdf",15);
		Field field_age = Person.class.getDeclaredField("age");
		field_age.setAccessible(true);//暴力反射
		System.out.println(field_age.get(person));

getDeclaredField

public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 name 参数是一个 String,它指定所需字段的简称。注意,此方法不反映数组类的 length 字段。 
注意:如果成员变量的属性是private,直接调用Class.getField(String name) 是无法获取的。

4.3 成员方法的反射

		Person person = new Person("bask", "boy",15);
		Method methodSetName = Person.class.getMethod("setName",String.class);
		methodSetName.invoke(person, "hello");
		System.out.println(person.toString());
如果是静态方法,Method.invoke(null,参数);

如果该函数不带参数呢?

	Method methodGetName = Person.class.getMethod("getName", null);
		System.out.println(methodGetName.invoke(person, null));

如果函数是多个参数

Class[] cls= new Class[]{String.class,String.class,int.class};
		Method methodSet = Person.class.getMethod("setPerson", cls);
		Object[] objs = new Object[]{new String("daoqin"),new String("bigboy"),23};
		methodSet.invoke(person, objs);
		System.out.println(person.toString());
如果传递的参数是一个数组

		Method setagesMethod = Person.class.getMethod("setages", int[].class); 
		setagesMethod.invoke(person, (Object)new int[]{128,18,15,16,17});
		System.out.println(person.toString());
注意:

invoke

public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。

如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。

如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

invoke函数的第二个参数是可变参数,如果直接传入一个数组对象,就会被拆解为多个Objext对象,不会被认为是一个数组对象,所以必须强制转化为Objext;

setagesMethod.invoke(person, (Object)new int[]{128,18,15,16,17});

4.4数组对象的反射

private static void printObject(Object object) {
		// TODO Auto-generated method stub
		Class cl = object.getClass();
		if(cl.isArray()){
			int len = Array.getLength(object);
			for (int i = 0; i < len; i++) {
				System.out.println(Array.get(object, i));
			}
		}
		else {
			System.out.println(object);
		}
		
	}
调用方式:

int[] a1 = new int[]{1,2,3};
		String[] a2 = new String[]{"abc","bcd"};
		
		printObject(a1);
		printObject(a2);

最后看下面这个代码:

	int[] a1 = new int[4];
		int [][] a2 = new int[2][3];
		Object object = a1;//正确 int[] 是一个Object对象
		Object[] objects = a2;//正确 理由同上
		Object[] objects2 = a1;//错误,int不是Objext对象















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值