美文网首页
java 泛型基础(详细例子)

java 泛型基础(详细例子)

作者: 付小影子 | 来源:发表于2018-07-26 15:36 被阅读0次

    Java基础之一反射

    package shadow.android.com.testkotlinapplication.reflect;
    ### 获取反射类类对象的三种方法
    /**
     * Author : shadow
     * Desc :反射 万事万物皆是对象 获取类类型Class的三种方法
     * Date :2018/7/25/025
     */
    
    public class ReflectClass {
        public static void main(String[] args) {
            System.out.println("hello");
            Foo foo = new Foo(); //Foo实例对象
            //c1 c2 c3都是Foo的类类型 Class的实例对象
            //方法1 :通过实例对象调用getClass方法
            Class c1 = foo.getClass();
            //方法2 :通过类名调用静态属性class方法
            Class c2 = Foo.class;
            try {
                //方法3:通过Class.froName(包名.类名方法调用)
                Class c3 = Class.forName("shadow.android.com.testkotlinapplication.reflect.Foo");
                System.out.print("c3 == c2 ");
                System.out.println(c3 == c2);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            //c1 c2 c3是三种不同的方法获取类类型 Class实体类,所以C1 = C2 = C3 = TRUE
            System.out.print("c1 == c2 ");
            System.out.println(c1 == c2);
    
            //可以通过类类型 Class 的实例对象c1,创建类的对象,调用类的方法
            try {
                Foo foo1 = (Foo) c1.newInstance();
                foo1.hello();
    
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
    class Foo { //Foo类的对象是 java.lang.Class
    
        public void hello() {
            System.out.println("hello foo");
        }
    }
    
    

    动态加载类的方法 editPlus配合cmd命令行调用 file-new-java,保存Java文件

    编译时刻加载的类:静态加载类,他需要加载所有可能用到的类

    class StaticOffice 
    {
        public static void main(String[] args) 
        {
            System.out.println("Hello World!");
            //new 对象 都是静态加载类,在编译的时刻就需要加载所有的可能用到的类
            //如果此时Test2不存在,那么Test1也会运行不成功
            if("Test1".equal(args[0])){
                Test1 t1 = new Test1();
                t.start();
            }
            
    
            if("Test2".equal(args[0])){
                Test2 t2 = new Test2();
                t2.start()
            }
            
        }
    }
    

    运行时刻加载的类,动态加载类

    动态加载类 不需要把所有的类都准备好,只是在用的时候,想用谁就调用谁
    所有此时无论是否Test1和Test2都存在或者只存在一个,那么程序都是可以正常运行的

    微信图片_20180726110310.png

    创建父类接口是为了耦合度降低,不必判断是t1或者是T2强转


    微信图片_20180726110314.png

    Test1和Test2分别实现基类


    微信图片_20180726110318.png 微信图片_20180726110322.png

    编译类 javac 类名.java,并且运行类 java 类名 传递过去的args参数


    微信图片_20180726110331.png

    保存到本地Java文件,以及编译后的class文件


    微信图片_20180726110327.png

    获取类信息,必须先获取类的类类型

    package shadow.android.com.testkotlinapplication.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * Author : shadow
     * Desc :Class类的基本api,能拿到任意类的全部信息,成员变量,成员函数等
     * Date :2018/7/26/026
     */
    
    public class ClassUtil {
        /**
         * @param obj 就是任意类
         */
        public static void printClassMethod(Object obj) {
            System.out.println("printClassMethod");
            //要获取任意类的信息,先获取类类型Class 实例
            Class c1 = obj.getClass();
            //获取所有的包含父类在内的所有的方法
            //方法是method的实例对象
            Method[] ms = c1.getMethods();
            //获取自己类的所有方法
            Method[] mds = c1.getDeclaredMethods();
            for (Method m : ms) {//遍历所有的方法,输出返回值类型 变量名 (参数类型)
                Class returnType = m.getReturnType(); //方法的返回值 类类型,比如int,string
                System.out.print(returnType.getName() + " "); //返回值类类型 类名全称
                System.out.print(m.getName() + "(");//方法名称
                Class[] params = m.getParameterTypes();
                for (Class param : params) { //变量参数类型
                    System.out.print(param.getName() + ",");
                }
                System.out.println(")");
            }
    
        }
    
        public static void printClassField(Object obj) {
            System.out.println("printClassField");
            //要获取任意类的信息,先获取类类型Class 实例
            Class c1 = obj.getClass();
            //获取所有的包含父类在内的所有的成员变量
            //成员变量的对象是Field,万事万物皆对象
            Field[] fs = c1.getFields();
            //获取自己类的所有方法
            Field[] fds = c1.getDeclaredFields();
            for (int i = 0; i < fds.length; i++) {
                Class type = fds[i].getType();//成员变量类型的类类型
                System.out.print(type.getName() + " "); //成员变量类型名称
                System.out.println(fds[i].getName()); //成员变量名称
    
            }
        }
    
        public static void printClassConstructors(Object obj) {
            System.out.println("printClassConstructors");
            //要获取任意类的信息,先获取类类型Class 实例
            Class c1 = obj.getClass();
            //获取所有的包含父类在内的所有public 构造方法
            Constructor[] cs = c1.getConstructors();
            //获取自己类的public构造方法
            Constructor[] cds = c1.getDeclaredConstructors();
            for (int i = 0; i < cds.length; i++) { //变量本类所有的public 构造方法
                System.out.print(cds[i].getName() + " "); //构造方法名称
                System.out.print("(");
                Class[] params = cds[i].getParameterTypes();
                for (int j = 0; i < params.length; j++) {
                    System.out.print(params[j].getName() + ";");//构造方法的参数类型名称
                }
                System.out.println(")"); //成员变量名称
            }
        }
    }
    
    

    方法的反射操作,获取方法必须先获取类信息,获取类信息必须先获取类类型Class

    package shadow.android.com.testkotlinapplication.reflect;
    
    import java.lang.reflect.Method;
    
    /**
     * Author : shadow
     * Desc :反射方法
     * Date :2018/7/26/026
     */
    
    public class ReflectMethodDemo {
        public static void main(String[] args) {
           /* Class c1 = String.class; //String类的类类型
            Class c2 = int.class;//int 类型的类类型
    
            System.out.println("c1.getName() "+c1.getName()); //java.lang.String 全称
            System.out.println("c1.getSimpleName() "+c1.getSimpleName()); //String 简单名称
            System.out.println("c2.getName() "+c2.getName()); //int
    
            String a = "hello shadow";
            ClassUtil.printClassMethod(a);*/
           //Person person = new Person();
         /*   System.out.println("===================打印所有方法=======================");
            ClassUtil.printClassMethod(person);
            System.out.println("=====================打印所有构造方法==================");
            ClassUtil.printClassConstructors(person);
            System.out.println("======================打印所有成员变量=================");
            ClassUtil.printClassField(person);*/
    
            //获取方法对象
            System.out.println("=======================方法对象的反射====================");
            try {
                Class c = Class.forName("shadow.android.com.testkotlinapplication.reflect.Person");
                Person person = (Person) c.newInstance();
                //获取带参数的方法,方法名和参数类型,下面 两种方法都可以获取指定的函数方法,
                // public Method getMethod(String name, Class<?>... parameterTypes)
                //Method m = c.getMethod("setName", new Class[]{String.class});
                Method m = c.getMethod("setName", String.class);
                //等同于person.setName("shadow");
                m.invoke(person, "shadow");
    
                //获取不带参数的方法
                Method m2 = c.getMethod("getName");
                //等同于 person.getName();
                Object o = m2.invoke(person);
                //获取getName() 方法返回值类型
                Class c2 = o.getClass();
                System.out.println("返回值类型类类型名称:" + c2.getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    class Person {
        public String name;
        private String age;
        protected String mobile;
        String address;
    
        public Person(String name, String age, String mobile, String address) {
            this.name = name;
            this.age = age;
            this.mobile = mobile;
            this.address = address;
        }
    
        public Person(String name, String age) {
            this.name = name;
            this.age = age;
        }
    
        public Person(String name, String age, String mobile) {
            this.name = name;
            this.age = age;
            this.mobile = mobile;
        }
    
        public Person() {
        }
    
        public String getName() {
            System.out.println("hello :" + name);
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getMobile() {
            return mobile;
        }
    
        public void setMobile(String mobile) {
            this.mobile = mobile;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
    

    泛型只在编译时期有效,为了避免输入错误,运行时期会去掉泛型

    package shadow.android.com.testkotlinapplication.reflect;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    /**
     * Author : shadow
     * Desc : 反射思考泛型
     * Date :2018/7/26/026
     */
    
    public class GenericityReflect {
        public static void main(String[] args){
            ArrayList list = new ArrayList();
            ArrayList<String> list1 = new ArrayList<>();
    
            list.add("shadow");
            list.add(20); //可以添加 string类型,int类型
    
            list1.add("hello");
            //list1.add(100); 并不能加进去
            System.out.println("反射前 list1.size = "+list1.size());
            System.out.println("反射前 list1 = "+list1);
    
            Class c1 = list.getClass();
            Class c2 = list1.getClass();
    
            //java中的泛型只在编译时期有效,为了防止输入错误,在运行时刻,会去掉所有泛型,所以c1 == c2
            System.out.println(c1 == c2 ); //true
    
            try {
                //获取Add方法的反射
                Method m = c2.getMethod("add",Object.class);
                m.invoke(list1,100);
                System.out.println("反射后 list1.size = "+list1.size());
                System.out.println("反射后 list1 = "+list1);
                //反射 是在运行时期执行的
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:java 泛型基础(详细例子)

          本文链接:https://www.haomeiwen.com/subject/daybmftx.html