内省——JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象。这些信息在类中用私有字段来存储,如果读取或者设置这些字段的值,则需要通过一些相应的方法访问。
一个类被当作JavaBean使用时,javaBean的属性是根据方法名推断出来的,它根本看不到Java类的内部成员。
示例:
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IntroSpactorTest
{
/**
* @param args
*/
public static void main(String[] args) throws Exception
{
// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
Object retVal = getProperty(pt1, propertyName);
System.out.println(retVal);
setProperty(pt1, propertyName);
System.out.println(pt1.getX());
}
private static void setProperty(ReflectPoint pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1,7);
}
private static Object getProperty(ReflectPoint pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
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;
}
}
public class ReflectPoint
{
private int x ;
public int y;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
public ReflectPoint(int x, int y)
{
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString()
{
return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3="
+ str3 + "]";
}
}
Java的注解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加则等于没有标记,以后,Java编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
注解的属性:1、字符串类型2、数组类型。3、枚举类型。4、注解类型。
示例:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.itcast.day1.EnumTest;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation
{
String color() default "blue";
String value();
int[] arrayAttr() default {2,3,4};
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}
public @interface MetaAnnotation
{
String value();
}
public class AnnotationTest
{
/**
* @param args
*/
@SuppressWarnings("deprecation")
@ItcastAnnotation("xyz")
public static void main(String[] args)
{
// TODO Auto-generated method stub
if(AnnotationTest.class.isAnnotationPresent
(ItcastAnnotation.class))
{
ItcastAnnotation annotation =
(ItcastAnnotation)AnnotationTest.class.getAnnotation
(ItcastAnnotation.class);
System.out.println(annotation);
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(annotation.arrayAttr().length);
System.out.println(annotation.lamp().nextLamp().name());
}
}
}
泛型
泛型是提供给Java编译器的使用,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器带类型说明的集合时会去除掉类型信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据,例如,用反射得到集合,再强调其add方法即可。
示例:
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
public class GenricTest
{
/**
* @param args
*/
public static void main(String[] args) throws Exception
{
// TODO Auto-generated method stub
ArrayList collection1 = new ArrayList();
collection1.add(1);
collection1.add(1L);
collection1.add("abc");
//int i = (Integer)collection1.get(1);
ArrayList<String> collection2= new ArrayList<String>();
collection2.add("1");
collection2.add("1L");
collection2.add("abc");
String str = collection2.get(2);
Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ArrayList<Integer> collection3 = new ArrayList<Integer>();
System.out.println(collection3.getClass()==collection2.getClass());
//collection3.add("abc");
//利用反射可以越过泛型的限制
collection3.getClass().getMethod("add",Object.class).invoke(collection3,"abc");
System.out.println(collection3.get(0));
printCollection(collection3);
Class<?> y;
Class<String> x;
//y = x;
HashMap<String,Integer> maps = new HashMap<String,Integer>();
maps.put("zxx", 28);
maps.put("lhm", 35);
maps.put("flx", 33);
Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> entry: entrySet)
{
System.out.println(entry.getKey()+":"+entry.getValue());
}
add(3,5);
Number x1 = add(3.5,3);
Object x2 = add(3,"abc");
String[] strs = {"a","b","c"};
Integer[] ints = {2,4,5,6};
swap(strs,1,2);
swap(ints,1,2);
for(String str3: strs)
{
System.out.println(str3);
}
for(Integer int2 : ints)
{
System.out.println(int2);
}
Object obj = "abc";
String x3 = autoConvert(obj);
copy1(new Vector<String>(),new String[10]);
copy2(new Date[10],new String[10]);
}
private static <T> void fillArray(T[] a,T obj)
{
}
private static <T> T autoConvert(Object obj)
{
return (T)obj;
}
public static <T> void swap(T[] a,int i,int j)
{
T temp = a[i];
a[i] = a[j];
a[j] = temp;
}
private static <T> T add(T x ,T y)
{
return null;
}
public static <T> void printCollection(Collection<T> collection,T obj)
{
System.out.println(collection.size());
collection.add(obj);
}
public static <T> void copy1(Collection<T> dest,T[] src)
{
}
public static <T> void copy2(T[] dest,T[] src)
{
}
}