Java基础增强3-反射,内省,beanutils,泛型
来源:互联网 发布:淘宝网购物女装牛仔裤 编辑:程序博客网 时间:2024/05/16 01:07
1、反射(reflect):(利用配置文件)
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。主要应用于框架,框架基于配置文件。
加载类:
//加载类的字节码 //1 常用 Class classz1 = Class.forName("seu.xinci.reflect.person"); //2 Class classz2 = Person.class; //3 Class callsz3 = new Person().getClass();
解剖类:
得到public:
Constructor getConstructorMethod getMethod
Field getField
得到private:
Constructor getDeclaredConstructor
Method getDeclaredMethod
Field getDeclaredField
获得构造方法:
@Test //反射类无参的构造方法 public Person() public void test1() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //利用Constructor创建对象 Class classz = Class.forName("seu.xinci.reflect.Person"); Constructor constructor = classz.getConstructor(); Object o = constructor.newInstance(null); System.out.println(o); }
@Test //反射类有参的构造方法 public Person(String name) public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //利用Constructor创建对象 Class classz = Class.forName("seu.xinci.reflect.Person"); Constructor constructor = classz.getConstructor(String.class); //制定参数类型,不是变量名称 Person o = (Person) constructor.newInstance("aa"); System.out.println(o); }
@Test //反射类私有的、有参的构造方法 private Person(int name) public void test3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //利用Constructor创建对象 Class classz = Class.forName("seu.xinci.reflect.Person"); Constructor constructor = classz.getDeclaredConstructor(int.class); //制定参数类型,不是变量名称 constructor.setAccessible(true); //暴力反射 Person o = (Person) constructor.newInstance(25); System.out.println(o); }
获得构造方法:
//反射无参 public void eat() @Test public void test() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Person person = (Person) classz.newInstance(); Method eat = classz.getMethod("eat", null); eat.invoke(person,null); }
<pre name="code" class="java">//反射有参 public void run(String address) @Test public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Method eat = classz.getMethod("run", String.class); eat.invoke(person,"北京"); }
</pre><pre>
//反射有参带返回值 public String test(String string) @Test public void test3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Method eat = classz.getMethod("test", String.class); String cs = (String) eat.invoke(person, "北京"); System.out.println(cs); }
//反射有参带返回值、私有方法 private String test2(String string) @Test public void test4() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Method eat = classz.getDeclaredMethod("test2", String.class); eat.setAccessible(true); //暴力反射 String cs = (String) eat.invoke(person, "北京"); System.out.println(cs); }
//反射有参带返回值、静态方法 public static String test3(String string) @Test public void test5() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Method eat = classz.getDeclaredMethod("test3", String.class); String cs = (String) eat.invoke(null, "北京"); System.out.println(cs); }
//反射mian方法 public static void main(String[] args) //通过反射调用带数组的方法时,要注意处理 @Test public void test6() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); //带包的名称:完整名称 Method eat = classz.getDeclaredMethod("main", String[].class); eat.invoke(null, (Object) new String[]{"1","2"}); }传一个数组容易出问题,因此,如果只传一个数组那么就要欺骗。(Object)
获得反射成员变量:
//反射类的字段 ---set public String name; @Test public void test1() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); Field name = classz.getField("name"); name.set(person,"fix"); System.out.println(person.getName()); }
//反射类的字段 ---get public String name; @Test public void test2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { Person person = new Person(); person.setName("xxx"); Class classz = Class.forName("seu.xinci.reflect.Person"); Field name = classz.getField("name"); String o = (String) name.get(person); System.out.println(o); }
//反射类的字段 ---set private int age; @Test public void test3() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { Person person = new Person(); Class classz = Class.forName("seu.xinci.reflect.Person"); Field name = classz.getDeclaredField("age"); name.setAccessible(true); name.set(person,123); System.out.println(person.getAge()); }
//反射类的字段 ---get private int age; @Test public void test4() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { Person person = new Person(); person.setAge(123); Class classz = Class.forName("seu.xinci.reflect.Person"); Field age = classz.getDeclaredField("age"); age.setAccessible(true); int o = (Integer) age.get(person); System.out.println(o); }
2、内省(introspector):
用于操作javabean对象。有什么get、set方法就有什么属性。
- 直接调用bean的setXXX或getXXX方法。
- 通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式。
- 通过PropertyDescriptor类操作Bean的属性
- 通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
//通过内省api操作bean的name属性 @Test public void test1() throws IntrospectionException, InvocationTargetException, IllegalAccessException { Student s = new Student(); PropertyDescriptor pd = new PropertyDescriptor("name",Student.class); Method writeMethod = pd.getWriteMethod(); writeMethod.invoke(s,"flx"); //System.out.println(s.getName()); Method readMethod = pd.getReadMethod(); String result = (String) readMethod.invoke(s, null); System.out.println(result); }
类继承object,object中有getClass(),所以会有class属性
//操作bean的所有属性 @Test public void test2() throws IntrospectionException { BeanInfo beanInfo = Introspector.getBeanInfo(Student.class); PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor is:pd){ System.out.println(is.getName()); } }
3、BeanUtils:
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。
所需文件:beanutils(commons-beanutils-1.9.2.jar),log4j(commons-logging.jar) (Apache公司)
实例:
//用beanUtils操作bean public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { Student s = new Student(); BeanUtils.setProperty(s, "name", "flx"); System.out.println(s.getName()); }自动的类型转换! 例如下面例子中的age字段!!////以下代码中的birthday是错误示例!!!
//用beanUtils操作bean public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { String name = "flx"; String password = "123"; String email = "flx@sina.com"; String age = "21"; String birthday = "1990-09-19"; Student s = new Student(); BeanUtils.setProperty(s, "name", name); BeanUtils.setProperty(s, "password", password); BeanUtils.setProperty(s, "email", email); BeanUtils.setProperty(s, "age", age); BeanUtils.setProperty(s, "birthday", birthday); System.out.println(s.getAge()); System.out.println(s.getBirthday()); }
可以自动进行8中基本类型的转换。但是birthday这种String类型的转换就不可以实现。
除了 这四类八种基础类型,剩下的java 一切类型 都是引用类型。那么 这四类八种基础数据类型是什么呢? 请看下面
第一类:整型 byte short int long
第二类:浮点型 float double
第三类:逻辑型 boolean(它只有两个值可取true false)
第四类:字符型 char
示例:ConverUtils 注册转化器!!!//用beanUtils操作bean public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { String name = "flx"; String password = "123"; String email = "flx@sina.com"; String age = "21"; String birthday = "1990-09-19"; Student s = new Student(); ConvertUtils.register(new DateLocaleConverter(),Date.class); BeanUtils.setProperty(s, "name", name); BeanUtils.setProperty(s, "password", password); BeanUtils.setProperty(s, "email", email); BeanUtils.setProperty(s, "age", age); BeanUtils.setProperty(s, "birthday", birthday); System.out.println(s.getAge()); System.out.println(s.getBirthday()); }
不能new接口的原因是接口里面有抽象的方法,但是如果我们在new的时候把抽象的方法实现了,那么就可以了。
实现自己的Convert转换器:
//用beanUtils操作bean public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { String name = "flx"; String password = "123"; String email = "flx@sina.com"; String age = "21"; String birthday = "1990-09-19"; Student s = new Student(); ConvertUtils.register(new Converter() { public Object convert(Class type, Object value) { if (value == null) { return null; } SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd"); Date date = null; try { date = formatter.parse((String) value); } catch (ParseException e) { throw new ConversionException(e); } return date; } }, Date.class); BeanUtils.setProperty(s, "name", name); BeanUtils.setProperty(s, "password", password); BeanUtils.setProperty(s, "email", email); BeanUtils.setProperty(s, "age", age); BeanUtils.setProperty(s, "birthday", birthday); System.out.println(s.getAge()); System.out.println(s.getBirthday()); }
操作bean的属性优先选用beanUtils
对于8种基本类型,用自带转换器。如果实在没有找到,自己去写。
4、泛型(generic):
为了保证程序的安全性,最典型的应用场景就是集合。 <>念着typeofJDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
泛型是给编译器用的。编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
整个ArrayList<Integer>称为参数化的类型ParameterizedType。
//泛型典型应用1 单列 @Test public void test1(){ List<Integer> list = new ArrayList<Integer>(); list.add(1); int i = list.get(0); }
取map集合一定用的是entryset()!!!
//泛型典型应用2 双列 @Test public void test2(){ Map<String,Integer> map = new LinkedHashMap<String, Integer>(); map.put("a",1); map.put("aa",2); Set<Map.Entry<String, Integer>> entries = map.entrySet(); for (Map.Entry<String, Integer> i:entries){ String key = i.getKey(); Integer value = i.getValue(); System.out.println(key + "=" + value); } }
使用泛型的注意事项:
- 使用泛形时,泛形类型须为引用类型,不能是基本数据类型。
- 定义变量只用对象,到底能调用什么方法由变量决定的。 一旦用到泛型,左右两边都应该一致,除非只用一边。
//ArrayList<String> list = new ArrayList<Object>(); 错误示例 //ArrayList<Object> list = new ArrayList<String>(); 错误示例 ArrayList<String> list = new ArrayList (); ArrayList list = new ArrayList<String>();
自定义泛型:
1、编写一个泛型方法,交换数组上的任意两个的元素。
public static void main(String[] args) { Integer arr1[]={1,2,3}; swap(arr1,0,1); System.out.println(Arrays.asList(arr1)); Byte arr2[]={'a','b','c'}; System.out.println(Arrays.asList(arr2)); } //编写一个泛型方法,交换数组上的任意两个位置的元素 不能确定传入数组的类型 @Test public static <T> void swap (T arr[],int pos1,int pos2){ T temp = arr[pos1]; arr[pos1] = arr[pos2]; arr[pos2] = temp; }2、编写一个泛型方法,接收一个任意数组,并颠倒数组中的所有元素:
public class Demo2 { public static void main(String[] args) { Integer arr[] = {1,2,3,4}; swap(arr); System.out.println(Arrays.asList(arr)); } //编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素 public static <T> void swap (T arr[]){ int start = 0; int end = arr.length-1; while(start <= end) { T temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } }}只有对象类型才能作为泛型方法的实际参数。
在泛型中可以同时有多个类型,例如:
public static <K,V> V getValue(K key) { return map.get(key);}
在类上面定义的泛型只对类的非静态成员有效!! 静态不需要进行new,也就不知道T
如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
public class GenericDao<T> {
private T field1;
public void save(T obj){}
public T getId(int id){}
}
如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
public class GenericDao<T> {
private T field1;
public void save(T obj){}
public T getId(int id){}
}
0 0
- Java基础增强3-反射,内省,beanutils,泛型
- Java - 基础增强 - 增强for - 可变参数 - 枚举 - 反射 - 内省 - 泛型
- java基础增强--自动装箱拆箱、增强for循环、可变参数、枚举类、内省、beanUtils
- Java的反射,内省,beanUtils工具
- Java基础--反射、内省
- java基础加强(反射、内省、BeanUtils工具类、类加载器、动态代理)
- 基础加强_JavaBean,反射和内省,BeanUtils工具
- java基础加强(枚举,反射,增强for循环,可变参数,自动拆箱装箱,内省)
- 高新技术<三>---> 反射、内省、BeanUtils
- java基础增强---反射
- Java 内省、JavaBean、BeanUtils
- Java 内省、JavaBean、BeanUtils
- java基础增强---JavaBean的内省操作
- java基础加强二 反射 内省
- JAVA基础之内省与反射
- (笔记十一)反射、JavaBean、内省、BeanUtils框架
- 反射(reflect)、内省(introspector)以及BeanUtils框架
- Java学习笔记之<反射、内省、BeanUtils包操作JavaBean的对比>
- 数据库设计技巧
- 彩色图像处理
- Arch安装参考
- fast incremental backup failed on standby database
- cloudify印象
- Java基础增强3-反射,内省,beanutils,泛型
- gcc编译动态库和静态库
- 根据经纬度计算当地时间
- 移动端关于select最佳兼容性解决方案(css)
- view自带方法的调用时间
- JavaScript原始类型和引用类型
- 单例模式
- C++ STL中常见的typename关键字的作用
- AFNetworking 3.0迁移指南