zoukankan      html  css  js  c++  java
  • java 类,基本类型,反射,内省

    1、首先java中每个类对象都有一个类字节码,都属于Class.

      java的9大基本数据类型:int、short、long、float、double、char、byte、boolen和void。它们对应的类与其对应的类对象是不一样的,如int.class==Integer.class返回false,但是Integer包装的基本数据类型是int,因此Integer.Type==int.class返回的是true。判断一个类是否基本数据类型 calss.isPrimitive()。基本数据类型的数组不是基本类型,是类,是Object的子类:即int[].class.isPrimitive返回false,int[].class.isArray返回true。基本数据类型不是对象,Object的子类,

    因此:Object[] a=new int[3];时候出错,如果是Object a=new int[3];则正确。

      基本数据类型的数组必须维数和类型相同得到的字节码类型才相同:

      

    2、java反射,首先反射能够通过类名获取类的字节码,然后获取各个属性,方法,构造方法等类的一切。如下方法:得到了类对象,方法和属性当然可以对对象进行操作了。

     public static void  MyTest(String cl){  //要求用户输入类的全路径
    	        
    	       try {  
    	           Class cla=Class.forName(cl);//根据类的全路径进行类加载,返回该类的Class对象  
    	            
               Object o=cla.newInstance();//获取cla的没有参数的对象,如果有有参数的构造函数则获取它的构造函数,然后创建。前提是对类有一定了解才用反射 Method[] method=cla.getDeclaredMethods();//利用得到的Class对象的自审,返回方法对象集合 for(Method me:method){//遍历该类方法的集合 System.out.println(me.toString());//打印方法信息 } System.out.println("********"); Field[] field=cla.getDeclaredFields();//利用得到的Class对象的自审,返回属性对象集合 for(Field me:field){ //遍历该类属性的集合 System.out.println(me.toString());//打印属性信息 } } catch (ClassNotFoundException e) { e.printStackTrace(); } }

      3、反射作用:最简单的用处 我有很多个对象 每个都不一样 我需要将他们拼接成我要的标准绘图串 不管什么对象 构造有什么区别 我直接反射属性名和属性值进行我要的操作 一个方法适配所有类 没反射你要为每一个类去写一个方法 因为每个类里面的属性名都不一样 不知道属性名就没法写 但有了反射 你一个属性名都不需要知道。比如:数据库里有很多个表格,每一个表格都有自己的属性,且属性的个数也不一样;同时没个表格都有相应的增删改查的操作,若不用反射你就必须每一个表格写一个增删改查的方法,麻烦切代码冗余大。利用反射,把类的参数传递进来(和上面的方法一样),这样得到所有的属性就可以相应的操作,就只需要写一次增删改查了。

      其实反射在框架中用的最多,在开发框架的时候很可能要用到用户定义的类,而框架是先设计好的,因此在构建框架的时候,利用反射就可以了,下面用一个简单的框架让大家明白:

    package framdemo;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Collection;
    import java.util.Properties;
    
    public class Framworkdemo {
    
    	public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
    
    		InputStream s=new FileInputStream("config.properties");
    		Properties c=new Properties();
    		c.load(s);
    		s.close();
    		//这里得到了类的名字
    		String className=c.getProperty("className");
    		 Collection collection=(Collection) Class.forName(className).newInstance();
    		 
    		 collection.add(new String("21"));
    		 collection.add(new String("21"));
    		 collection.add(new String("321"));
    		 
    		 System.out.println(collection.size());
    		
    	}
    
    }
    

      看代码知道,我们的collection是读的配置文件里的类名className得到的具体的集合类,也就是说我们写着代码的时候,类型还没有确定。当我们把这个“小框架”给用户用的时候,用户只需要修改配置文件里的className对应的类即可。下面给出工程目录和配置文件:

     配置文件config.properties:

    className=java.util.HashSet
    

     当用户想用ArrayList集合或者自己定义的类的集合时候,只需要修改className对应的值即可,上面的框架就是典型的反射,我们不知道这个集合的类型,但是我们写好了框架实现的功能,这里相信大家了解了反射的作用了吧。

     4、内省,内省和反射有很多相像的地方,都是不知道具体类时候操作类的属性值,在框架中用的比较多。最重要的的区别是内省是对javaBean类操作的,JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中。javaBean类必须有无参数的构造方法,且set和get方法都必须遵循一定的规范,如Person 的2个属性age、name;则必须定义为getName、setName,age也一样这么定义。有些特别的属性名如CPU等,这时候设置方法名的时候就看属性的第二个字符是大写还是小写,如CPU,第二个大写,因此方法名为getCPU,setCPU。内省在访问属性和设置属性值时候得到类描述后直接获取方法,而反射需要遍历所有的属性和方法获得。

    内省是先的到类的描述符,然后得到相应的读写方法,即get和set方法,然后对其访问和操作的。

    (1)得到单个的属性,并操作

    public static void main(String[] args) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    
    		String property="age";//属性字符串
    		Testjavabean test=new Testjavabean();//对象,类似于反射先可能不知道,同反射一样获取对象也可以
    		PropertyDescriptor p1=new PropertyDescriptor(property, Testjavabean.class);//获得类对象的属性描述
    		
    		Method me=p1.getReadMethod();
    		Object o=me.invoke(test);
    		System.out.println(o);
    		
    		Method me2=p1.getWriteMethod();
    		Object o2=me2.invoke(test, 2);
    		System.out.println(me.invoke(test));//输出为2,表示成功
    		
    	}
    

     (2)可以得到类的所有属性,并操作:

    BeanInfo bi = Instospector.getBeanInfo(beanClass);//获取Bean描述对象
    PropertyDescriptor[] pds = bi.getPropertyDescriptors();//获取属性描述对象数组 

    pds[i].getName()得到属性字符串,然后对上面的单个属性操作一样进行相应的操作。

    内省的操作具体可以看:http://www.cnblogs.com/peida/archive/2013/06/03/3090842.html

    (3)由上看,在设置和范文属性的时候很麻烦,而且如果set属性值的时候如果类型不匹配就会报错,因此我们可以用第三方的工具包,是apach提供的:

     BeanUtils工具包:

      Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包。
      BeanUtils工具包:下载:http://commons.apache.org/beanutils/ 注意:应用的时候还需要一个logging包 http://commons.apache.org/logging/
      使用BeanUtils工具调用静态方法如:

    BeanUtils.setProperty(userInfo, "birthday.time","111111");
    直接访问和设置属性,但值得注意的是,它提供了2种方式访问和设置属性即:
    import org.apache.commons.beanutils.BeanUtils;
    import org.apache.commons.beanutils.PropertyUtils;
    前面一个可以自动转型,如果设置整型的时候,是以字符串传进去,它会自定转化为整型赋值,get时候总是字符串。
    后一个:get和set都是与原数据一样,若set整型值时候传入字符串就会报异常。具体看连接http://www.cnblogs.com/peida/archive/2013/06/03/3090842.html
    public class Neixing {
    
    	public static void main(String[] args) throws Exception {
    
    		String property="age";//属性字符串
    		Testjavabean test=new Testjavabean();//对象,类似于反射先可能不知道,同反射一样获取对象也可以
    		PropertyDescriptor p1=new PropertyDescriptor(property, Testjavabean.class);//获得类对象的属性描述
    		
    		Method me=p1.getReadMethod();
    		Object o=me.invoke(test);
    		System.out.println(o);
    		
    		
    		
    		Method me2=p1.getWriteMethod();
    		Object o2=me2.invoke(test, 2);
    		System.out.println(me.invoke(test));//输出为2,表示成功
    		
    		 BeanUtils.setProperty(test, property, 28);
    		 String agenuber=BeanUtils.getProperty(test, "age");
    		 System.out.println(agenuber);
    		 System.out.println(test.getAge());
    		 
    		 PropertyUtils.setProperty(test, "age", 12);
    		 System.out.println(test.getAge());
    		 PropertyUtils.setProperty(test, "age", "12");//出错,类型不匹配异常
    		 System.out.println(test.getAge());
    		 
    	}
    
    }
    

     工程目录:

     

  • 相关阅读:
    反射获取成员方法并运行
    反射获取成员变量,并修改值
    反射获取私有的构造方法运行
    反射获取构造方法并运行的快速的方式
    通过反射,获取有参数的构造方法并运行
    ssh端口映射
    python常见环境安装
    hadoop fs管理文件权限
    oracle通过DBlink连接mysql(MariaDB)
    [mysq]ERROR 2006 (HY000) at line xx: MySQL server has gone away 解决方法
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/4781919.html
Copyright © 2011-2022 走看看