`

黑马程序员_java高新(三)_内省、泛型、注解

 
阅读更多

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

 

内省——JavaBean

 

 

JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且

 

 

法名符合某种命名规则。

 

 

Javabean示例:

 

 

class Person {
	
	private String name;
	
	private int age;

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

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

 

 

JavaBean中属性的名称参考自它的getset方法。

 

 

如代码中的setAge()方法,属性名就为age,规则为:

 

 

如果set后的第二个字母是小写,则把第一个字母改为小写;

 

 

setTime-à属性为time

  

 

setCPU-à属性名为CPU

 

 

//根据JavaBean的属性名称创建PropertyDescriptor对象
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		
		//获取get方法
		Method methodGetX = pd.getReadMethod();
		
		//调用这个get方法
		Object retVal = methodGetX.invoke(pt1);
		
		System.out.println(retVal);
		
		
		//根据JavaBean的属性名称创建PropertyDescriptor对象
		PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass());
		
		//获取set方法
		Method methodSetX = pd.getWriteMethod();
		
		methodSetX.invoke(pt1);
		
		System.out.println(pt1.getX());

 

 

 

另一种较为复杂的方式:

 

 

BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal = null;
		for(PropertyDescriptor pd : pds) {
			if(pd.getName().equals(propertyName)){
				Method methodGetX = pd.getReadMethod();
				retVal = methodGetX.invoke(pt1);
				break;
			}
		}
		
		return retVal;

 

-------------------------------------------------------------------------------------------------------------------------

 

注解:

 

 

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以

 

 

后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标

 

 

记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

 

 

 

@Deprecated

 

表示该方法已经过时。

 

 

@Override

 

表示该方法是重写方法。

 

 

自定注解类:

 

 

元注解Retention的三种取值:

 

 

RetetionPolicy.SOURCE

 

RetetionPolicy.CLASS

 

RetetionPolicy.RUNTIME;

 

 

分别对应:java源文件-->class文件-->内存中的字节码。

 

 

 @Target可以定义注解使用的位置。

 

 

通过反射来获得注解:

 

 

if(AnotationTest.class.isAnnotationPresent(ItcastAnotation.class)){
			ItcastAnotation anotation = AnotationTest.class.getAnnotation(ItcastAnotation.class);
			System.out.println(anotation);
		}

 

 

数组类型的属性:

 

int [] arrayAttr() default {1,2,3};

 

 

@MyAnnotation(arrayAttr={2,3,4})

 

 

如果数组属性中只有一个元素,这时候属性值部分可以省略大括。

 

 

@ItcastAnotation(color="red",value="abc",arrayAtt=1)

 

 

枚举类型的属性:

 

 

EnumTest.TrafficLamp lamp() ;

 

 

@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)

 

 

注解类型的属性:

 

 

MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");

 

 

@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )

 

 

可以认为上面这个@MyAnnotationMyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个

 

 

@MetaAnnotationMetaAnnotation类的一个实例对象,调用代码如下:

 

 

         MetaAnnotation ma =  myAnnotation.annotationAttr();

 

         System.out.println(ma.value());

 

 

注解类代码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
	String color() default "blue";
	String value();
	int[] arrayAttr() default {3,4,4};
	EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
	MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}

 

----------------------------------------------------------------------------------------------------------------------

 

泛型:

 

 

JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

 

 

泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器

 

 

编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,

 

 

getClass()方法的返回值和原始类型完全一样。

 

 

整个称为ArrayList<E>泛型类型

 

 

ArrayList<E>中的E称为类型变量或类型参数

 

 

整个ArrayList<Integer>称为参数化的类型

 

 

ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数

 

 

ArrayList<Integer>中的<>念着typeof

 

 

ArrayList称为原始类型

 

 

参数化类型不考虑类型参数的继承关系,如下两种定义方法是错误的:

 

Vector<String> v = new Vector<Object>();

 

Vector<Object> v = new Vector<String>();

 

 

好处:

 

 

1.将运行时期出现问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时

 

 

问题减少,安全。

 

 

2,避免了强制转换麻烦。

 

 

泛型格式:通过<>来定义要操作的引用数据类型。

 

 

通常在集合框架中很常见,

 

 

只要见到<>就要定义泛型。

 

 

其实<> 就是用来接收类型的。

 

 

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 

 

只有引用类型才能作为泛型方法的实际参数。

 

 

在异常处理时,catch中不能够使用泛型参数,必须明确指定要捕获的异常类型,而throw可以抛出一

 

 

个泛型参数化的异常。

 

 

 泛型类:

 

 

当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。

 

 

//泛型前做法。
class Tool
{
	private Object obj;
	public void setObject(Object obj)
	{
		this.obj = obj;
	}
	public Object getObject()
	{
		return obj;
	}
}

//泛型做法
class Utils<T>
{
	private T q;
	public void setObject(T q)
	{
		this.q = q;
	}
	public T getObject()
	{
		return q;
	}
}

 

 

 泛型方法:

 

 

泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型

 

 

后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将

 

 

泛型定义在方法上。

 


传入参数类型不同的情况(将取两种类型的交集):

 

 

Number x1 = add(3.5,5);
	
	Object x2 = add(3,"abc");
	
	//String x3 = add(3,"abc");错误,当传入的两个类型不一样时,将会取它们的交集类型
	
	public static <T> T add(T x, T y) {
		return null;

 

 

 特殊之处:

 


静态方法不可以访问类上定义的泛型。

 

 

如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

 

 

public <Q> void print(Q q)
	{
		System.out.println("print:"+q);
	}
	public  static <W> void method(W t)
	{
		System.out.println("method:"+t);
	}

 

 

泛型定义在接口上:

 

//泛型定义在接口上。
interface Inter<T>
{
	void show(T t);
}

class InterImpl<T> implements Inter<T>
{
	public void show(T t)
	{
		System.out.println("show :"+t);
	}
}

 

 

泛型限定:

 

 

? 通配符。也可以理解为占位符。使用?通配符可以引用其他各种参数化的类型,?通配符定义的

 

 

变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

 


? extends E: 可以接收E类型或者E的子类型。上限。

 

? super E: 可以接收E类型或者E的父类型。下限
 

 

 

 

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics