javaweb_Ⅵjava基础增强——反射
学习框架的基础
反射:加载类,并解剖出类的各个组成部分。
加载类:
ps:
获取下列有什么用
构造函数:原,创建对象完成对象初始化。用来创建对象
方法:原,完成某个功能。使用该方法
成员变量:原,封装数据。给字段封装数据
①反射构造方法
// 解剖(反射类)构造函数并创建类的对象 @Test public void testss () throws Exception { // 先加载类,后解剖(反射) // public Person() Class cla = Class . forName( "com.ttt.eclipse.Person"); Constructor c = cla .getConstructor (null );//得到构造方法 Person p = (Person ) c. newInstance (null );//创建新对象 System. out. println( p. name); /* * 等效代码 * Class cla = Class.forName("com.ttt.eclipse.Person"); * Person p =(Person) cla.newInstance(); */ } @Test public void testsss () throws Exception { // public Person(String name) Class claa = Class . forName( "com.ttt.eclipse.Person"); Constructor c1 = claa . getConstructor( String. class ); Person p1 = (Person ) c1 .newInstance ("ss" ); System. out. println( p1. name); } @Test public void testssss () throws Exception { // private Person(List list)-->使用getDeclaredConstructor(构造函数变量使用的类)(反射私有构造函数) Class claa = Class . forName( "com.ttt.eclipse.Person"); Constructor c1 = claa. getDeclaredConstructor (List . class); c1 .setAccessible ( true); // 暴力反射,将访问权限设置为true Person p1 = (Person ) c1 .newInstance ( new ArrayList()); System. out. println( p1. name); }
②反射方法
// 反射类的方法: public void a(){} @Test public void test1 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getMethod ("a" , null ); m. invoke (p , null ); } // public void a(String naem, int passward) @Test public void test2 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getMethod ("a" , String .class , int .class ); m .invoke (p , "xx" , 38); } // public Class[] a(String name, int[] passward) @Test public void test3 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getMethod ("a" , String .class , int [].class ); Class cs[] = ( Class[]) m. invoke( p, "aaa" , new int[] { 1 , 2, 3 }); System. out. println( cs[ 0]); } // private void a(InputStream in) private // -->getDeclaredMethod(),setAccessible暴力反射 @Test public void test4 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getDeclaredMethod ("a" , InputStream .class ); m .setAccessible ( true); m .invoke (p , new FileInputStream ("D:\\1.txt" )); } // public static void a(int num) 静态方法,调用的时候不用创建对象 @Test public void test5 () throws Exception { Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getMethod ("a" , int .class ); m .invoke ( null, 23 ); } // public static void main(String[] args) 反射调用接收数组时注意使用(Object)来修饰 // invoke(对象,参数)方法的参数! @Test public void test6 () throws Exception { Class claz = Class . forName( "com.ttt.eclipse.Person"); Method m = claz. getMethod ("main" , String [].class ); m .invoke ( null, ( Object) new String[] { "a" , "b" }); // (Object) // --》兼容性强制转换成Object // 使编译器以为其不是数组,则可以调用该方法 }
③反射字段
// public String name = "s"; @Test public void test1 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Field f = claz .getField ("name" ); // 获取值 Object obj = f .get (p ); // 获取类型 Class type = f. getType(); if (type .equals (String . class)) { String sv = (String ) obj ; System. out. println( sv); } } // private int passward; @Test public void test2 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Field f = claz .getDeclaredField ("passward" ); f .setAccessible ( true); // 获取值 Object obj = f .get (p ); // 获取类型 Class type = f. getType(); if (type .equals ( int. class)) { int sv = (Integer ) obj ; System. out. println( sv); } } // private static int age; @Test public void test3 () throws Exception { Person p = new Person(); Class claz = Class . forName( "com.ttt.eclipse.Person"); Field f = claz .getDeclaredField ("age" ); f .setAccessible ( true); // 获取值 Object obj = f .get (p ); // 获取类型 Class type = f. getType(); if (type .equals ( int. class)) { int sv = (Integer ) obj ; System. out. println( sv); } }
javaweb_Ⅶjava基础增强——内省
内省?
专门用来操作Bean的属性
Bean的属性?
javabean:封装用户属性的类
bean的属性:封装之后对外界提供的各种set/get方法(set+get是一对,继承Object的getclass()算一个属性)。
Introspector类,getBeanInfo方法内省想要操作的类
例:
public class Person {//4个属性,3个的Person,一个class的属性 private String name; private String password; private int age; public String getName() { return name ; } public void setName (String name) { this .name = name; } public String getPassword() { return password ; } public void setPassword (String password) { this .password = password; } public int getAge() { return age ; } public void setAge (int age) { this .age = age; } } @Test public void test1 () throws Exception { BeanInfo bi = Introspector . getBeanInfo( Person. class , Object .class );// 将后面Object的属性省略 PropertyDescriptor [] ps = bi. getPropertyDescriptors(); // 属性编辑器,得到Bean的所有属性 for (PropertyDescriptor pd : ps) { System. out. println( pd. getName()); } } @Test public void test2 () throws Exception { Person p = new Person(); PropertyDescriptor pd = new PropertyDescriptor( "age" , Person .class ); Method m = pd .getWriteMethod ();// 得到setAge方法 m .invoke (p , 41); // 为其赋值 m = pd .getReadMethod ();// 得到getAge方法 System. out. println( pd. getPropertyType ());// 得到age的数据类型 System. out. println( m .invoke (p , null )); }
后面的Beanutils对bean操作会更简单,这里仅仅是了解获取属性的机制。
javaweb_Ⅷjava基础增强——BeanUtils
BeanUtils工具包是由Apache公司所开发,主要是方便对Bean类能够进行简便的操作。
public class Demo1 { //最简单的用法 @Test public void test1 () throws Exception { Person p = new Person(); BeanUtils. setProperty (p , "name", "xxc" );// 设置名字,这种转换只支持8种基础数据类型,复杂类型需要注册转换器 System. out. println( p. getName()); } // 复杂类型添加转换器 // beanutils框架 @Test public void test2 () throws IllegalAccessException , InvocationTargetException { String brithday = "null" ; // 注册数据转换器框架 ConvertUtils .register ( new Converter() { @SuppressWarnings ("unchecked" ) @Override public < T> T convert( Class< T> arg0, Object value) { // 数据检查 if (value == null ) { return null ; } // 是否是value if (!(value instanceof String )) { throw new ConversionException ("仅支持String类型" ); } String str = (String ) value ; // 值是否为空 if (str .trim ().equals ("" )) { return null ; } SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd" ); try { // String->Date return ( T) df. parse( str); } catch ( ParseException e ) { throw new RuntimeException (e ); } } }, Date. class ); // 阿帕奇自带的Date转换器,有bug,当传入Date数据为null时,产生异常。 // ConvertUtils.register(new DateLocaleConverter(), Date.class); // 注册转换器之后就可以进行属性设置 Person p = new Person(); BeanUtils. setProperty (p , "brithday", brithday); System. out. println( p. getBrithday ()); } beanutils允许使用map对bean的属性批量填充 @Test public void test3 () throws IllegalAccessException , InvocationTargetException { Map map = new HashMap (); map. put ("name" , "aa" ); map. put ("password" , "123" ); Person p = new Person(); BeanUtils. populate (p , map); // Map批量填充 System. out. println( p. getName()); System. out. println( p. getPassword ()); } }
javaweb_Ⅸjava基础增强——泛型(generic)
public class Demo1 { @Test public void test1 () { List< String> list = new ArrayList< String>(); // 定义泛型 list .add ("a" ); list .add ("b" ); list .add ("c" ); // 传统方式迭代器取数据 Iterator< String> it = list. iterator(); while ( it. hasNext()) { String value = it .next (); System. out. println( value); } // for增强 for (String s : list) { System. out. println( s); } } @Test public void test2 () { Map< Integer, String> map = new LinkedHashMap< Integer, String>(); // Linked遍历出来按照插入顺序遍历,HashMap根据Hash算法排序 map .put (1 , "a" ); map .put (2 , "b" ); map .put (3 , "c" ); // 普通迭代器 Set< Map. Entry< Integer, String>> set = map. entrySet(); Iterator< Map. Entry< Integer, String>> it = set. iterator(); while ( it. hasNext()) { Map. Entry< Integer, String> entry = it. next(); int key = entry .getKey (); String value = entry .getValue (); System. out. println( key + ":" + value); } // 增强for循环,省去迭代器 for (Map .Entry <Integer , String > entry : map. entrySet()) { int key = entry .getKey (); String value = entry .getValue (); System. out. println( key + ":" + value); } } }
注意事项:
泛型类型为引用类型(是Integer,不是int)
用泛型时,如果两边都是用的泛型,两边声明泛型必须类型一致
ArrayList<E>:泛型类型 :E叫做参数类型变量
ArrayList<Integer>:参数化类型:Integer叫做市级类型参数
public class Demo2 { // 自定义泛型方法,先声明,再使用。 public < T> void a(T t) { } public < T, E, K > void b( T t , E e, K k ) { } } /* * 还可以在类上面声明泛型 * 其泛型仅作用非静态方法上面 * public class Demo2<T,K,E>{ * * public void test1(T t){ * } * public void test2(T t,K k,E e){ * } * * public static <T> void test3(T t){ * } * * } * */ 小练习 // 实现指定位置数组元素的交互 public < T> void swap( T arr[], int pos1 , int pos2 ) { T temp = arr [pos1 ]; arr [pos1 ] = arr [pos2 ]; arr [pos2 ] = temp ; System. out. println( arr[ 0] + "," + arr[ 1]); } // 接收任意一个数组,并颠倒数组中的元素 public < T> void reverse( T arr[]) { int start = 0; int end = arr .length - 1 ; while ( true) { if (start >= end ) { break ; } T temp = arr [start ]; arr [start ] = arr [end ]; arr [end ] = temp ; start ++; end --; } for ( T a : arr) { System. out. println( a); } } }
用了5天学了一天的东西 效率好低>_<