精华内容
下载资源
问答
  • 下面小编就为大家带来一篇java中利用反射调用另一private方法的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 1.存在无参构造的情况: public T newInstance() throws InstantiationException, IllegalAccessException 除了第一种方法...于是取得了Class对象有一个最直接的好处:可以通过反射实例化对象。 public ...

    1.存在无参构造的情况:

    public T newInstance()
           throws InstantiationException, IllegalAccessException
    

    除了第一种方法(getClass())会产生Date类的实例化对象之外,其他的两种都不会产生Date类的实例化对象。
    于是取得了Class类对象有一个最直接的好处:可以通过反射实例化对象。

    public class Test {public static void main(String[] args)  throws
    		ClassNotFoundException,InstantiationException, IllegalAccessException {
    		Class<?> cls = Class.forName("java.util.Date") ;
    		// 实例化对象,等价于 new java.util.Date();				   
    		Object obj = cls.newInstance() ; 
    		System.out.println(obj);}
    }
    

    2.不存在无参构造的情况

    public T newInstance(Object ... initargs) throws
     InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetExceptio
    

    Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class类调用,只能够通过明确的构造调用实例化处理。

    package getConstructioMethod;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    class Person {
    	private String name ;
    	private int age ;
    	public Person(String name,int age) {
    	this.name = name ;this.age = age ;
    }
    @Override
    public String toString() {
    	return "Person [name=" + name + ", age=" + age + "]";
    	}
    }
    public class Test {public static void main(String[] args) throws InstantiationException,IllegalAccessException, NoSuchMethodException, SecurityException,IllegalArgumentException, InvocationTargetException {
    	Class<?> cls = Person.class ;// 取得指定参数类型的构造方法对象
    	Constructor<?> cons = cls.getConstructor(String.class,int.class);
    	System.out.println(cons.newInstance("fwb",21));
    	}
    }
    
    展开全文
  • java反射实例化对象

    万次阅读 2018-06-08 13:43:41
    可通过Class提供的方法为一个类实例化对象,区别与new关键字创建对象,前者是在已经编译好的情况下,通过指定类名来创建实例化对象,后者是在编译之后之间创建实例化对象。也可通过Class在运行时获得某个...

    -Class类

    Java中手动创建的每一个类,在编译后JVM都会为其创建一个Class类对象,在这个Class类对象中保存了所建类的信息。

    可通过Class类提供的方法为一个类实例化对象,区别与new关键字创建对象,前者是在类已经编译好的情况下,通过指定类名来创建实例化对象,后者是在编译之后之间创建实例化对象。

    也可通过Class类在运行时获得某个类对象的信息。

    下面是获取Class类对象的三种方法。

    package org.test;
    /** 
     * @ClassName: TestDemo
     * @Description: 获取Class类对象的三种方法
     * @author 王逍遥
     * @date 2018-6-8 下午1:13:56 
     */
    class Person{}
    public class TestDemo {
    	public static void main(String args[]) throws ClassNotFoundException{
    		Person per = new Person();
    		/*
    		 * getClass()取得Person的Class类对象,Object类提供此方法
    		 * 看源码可知getClass()返回的是Class<?>,per.getClass()取得的就是Person类的Class类对象
    		 * */
    		System.out.println(per.getClass().getName());   //输出Class类对象中Person类的信息
    		
    		Class<?> cls = Person.class;	//Person.class,取得Person类的Class类对象
    		System.out.println(cls.getName());	  //输出Class类对象中Person类的信息
    		
    		Object obj = Class.forName("org.test.Person");
    		System.out.println(obj.getClass().getName());
    		
    		Class<?> cls2 = Class.forName("org.test.Person");	//forName通过全限定名获取Class类对象
    		System.out.println(cls2.getName());	  //输出Class类对象中Person类的信息
    	}
    }

    通过反射实例化对象:

    package org.test;
    /** 
     * @ClassName: TestDemo02 
     * @Description: 反射实例化对象
     * @author 王逍遥
     * @date 2018-6-8 下午1:13:56 
     */
    class Person {
    	public Person() {
    		System.out.println("**************");    //由这个输出可知,反射实例化对象也要调用构造方法
    	}
    }
    public class TestDemo {
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{ 
    		Class<?> cls = Class.forName("org.test.Person");	//通过类全限定名获取Person的Class类对象
    		Person per = (Person) cls.newInstance(); // newInstance()实例化对象
    		System.out.println(per);
    	}
    }

    newInstance()在运行时实例化对象,关于运行时这一点,可以参考工厂模式与反射的结合,即只需要更改主方法中的类全限定名参数,就可以增加实例化对象。

    -总结

    Java可以通过反射机制来实例化一个对象,也可用反射调用构造方法,指定构造方法参数,另外还有反射调用方法、属性等。反射加强了Java的配置性和扩展性(比如反射与工厂模式的集合),Spring框架提供的许多功能都是Java反射来实现,SpringIoC就是。

    另外疑问ssm框架中许多可写在Java代码中的内容都用*.xml来代替,这是否也与反射相关呢?

    补上反射调用构造方法,方法的代码:

    package org.test;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    /** 
     * @ClassName: Temp 
     * @Description: 反射调用构造方法
     * @author 王逍遥
     * @date 2018-6-11 上午8:34:07 
     */
    class Person(){
    	private String name;
    	private int age;
    	public Person(){}
    	public Person(String name, int age) {
    		this.name = name ;
    		this.age = age ;
    		System.out.println("------------------");
    	}
    	public String toString() {
    		return "姓名:" + this.name + ",年龄:" + this.age;
    	}
    }
    public class Temp {
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
    		Class<?> cls = Class.forName("org.test.Person");
    		//创建per对象,无参
    		Person per = (Person) cls.newInstance();
    		System.out.println(per);
    		//构造参数创建对象,添加参数
    		Constructor<?> cons=null;
    		cons=cls.getConstructor(String.class,int.class);//获取指定参数的构造方法
    		Person per2 = (Person) cons.newInstance("hehe",3);//创建新对象时调用构造方法
    		System.out.println(per2);
    	}
    }
    package org.test;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /** 
     * @ClassName: ReflectDemo03 
     * @Description: 反射调用普通方法
     * @author 王逍遥
     * @date 2018-6-11 上午8:47:15 
     */
    class Person{
    	//无参无返回值
    	public void test(){
    		System.out.println("heiheiheihei");
    	}
    	//有参无返回值
    	public void test02(String temp){
    		System.out.println(temp);
    	}
    	//有参有返回值
    	public String test03(String temp){
    		return temp;
    	}
    }
    public class ReflectDemo03 {
    	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		Class<?> cls=Class.forName("org.test.Person");
    		//提供一个统一的对象来调用方法
    		Object obj = cls.newInstance();
    		
    		//无参无返回值
    		Method met = cls.getMethod("test");
    		met.invoke(obj);
    		
    		//有参无返回值
    		Method met2 = cls.getMethod("test02", String.class);
    		met2.invoke(obj, "hehehehehe");
    		
    		//有参有返回值
    		Method met3 = cls.getMethod("test03", String.class);
    		//用re来接收返回的内容
    		Object re = met3.invoke(obj, "hahahahaha");
    		System.out.println(re);
    	}
    }
    


    展开全文
  • 主要介绍了Java反射如何修改private final成员变量值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • spring中应用反射实例化bean

    千次阅读 2017-10-16 21:56:08
    一 反射源头Class的概念我们已经非常熟悉了。比如可以有Student这个,Person这个。...反射方式:实例化对象—>getClass()方法—>通过完整的类名   一个简单的例子:   package cn.

    一  反射源头Class类

    对类的概念我们已经非常熟悉了。比如可以有Student这个类,Person这个类。但是我们要知道,有一个叫Class的类,它是反射的源头。

     

    正常方式:通过完整的类名—>通过new实例化—>取得实例化对象

    反射方式:实例化对象—>getClass()方法—>通过完整的类名

     

    一个简单的例子:

     

    package cn.classes;

    public class OneClass {

    }


    package cn.test;

    import cn.classes.OneClass;

    public class Test {
        public static void main(String[] args) {
            OneClass c = new OneClass();
            
    System.out.println(c.getClass().getName());
       }
    }

    输出结果:cn.classes.OneClass


    我们需要使用反射,就要获得Class这个类,有三种方法:

    package cn.classes;

    public class OneClass {

    }


    import cn.classes.OneClass;

    public class Test {
    public static void main(String[] args) {
         Class<?> c1 = null;
         Class<?> c2 = null;
         Class<?> c3 = null;

         try 
        {
             // 方法一:forName(重要)
             
    c1 = Class.forName("cn.classes.OneClass");
        } 
        catch (ClassNotFoundException e) 
        {
             e.printStackTrace();
        }
         // 方法二
         
    c2 = new OneClass().getClass();
      
         // 方法三
         c3 = OneClass.class;

         System.out.println(c1.getName());
         System.out.println(c2.getName());
         System.out.println(c3.getName());
       }
    }

    输出结果:cn.classes.OneClass

     

     

    二 利用Class这个类实例化类

     

    ①无参构造

    package cn.classes;

    public class Person {
        private String name;
        private int age;

         .............省略getter,setter..............

        @Override
        public String toString()
        {
              return "Person [name=" + name + ", age=" + age + "]";
        }

    }


    package cn.test;

    import cn.classes.Person;

    public class Test
    {
        // 这样做必须在类中有一个空构造方法
        public static void main(String[] args)
        {
                  Class<?> c = null;
                   try
                   {
                          
    c = Class.forName("cn.classes.Person");
                          
    Person p = (Person)c.newInstance();
                          p.setName("xy");
                          p.setAge(20);
                          System.out.println(p);
                   } 
                  catch (Exception e)
                  {
                          e.printStackTrace();
                   }  
         }
    }

     

    ②有参构造

    package cn.classes;

    public class Person
    {
        private String name;
        private int age;

         public Person(Stringname,int age){

                     this.name = name;

                     this.age = age;

        }

        .............省略getter,setter..............    

        @Override
        public String toString()
        {
              return "Person [name=" + name + ", age=" + age + "]";
        }
    }


    package cn.test;

    import Java.lang.reflect.Constructor;

    import cn.classes.Person;

    public class Test
    {
        // 如果没有一个空构造方法
        public static void main(String[] args)
        {
              Class<?> c = null;
              try
              {
                      
    c = Class.forName("cn.classes.Person");
                      
    Constructor<?> con = c.getConstructors(String.class,int.class);
                      Person p = (Person)con.newInstance("xy",20);
                      System.out.println(p);
              } 
             catch (Exception e)
             {
                    e.printStackTrace();
             }  
        }
    }

     

    三 Spring中使用Class实例化

    bean.xml
    <bean id="id" class="com.xy.Student" />

     

    Spring将采用的代码创建代码Java实例
    Class c = Class.forName("com.xy.Student");
    Object bean = c.newInstance();

     

     

    四 Class类调用方法

    package cn.classes;

    public class Person
    {
        public void add()
        {
               System.out.println("add");
        }

        public void addWithParameters(String name, int age)
        {
                System.out.println("add带参数方法" + name + age);
        }
    }


    package cn.test;

    import java.lang.reflect.Method;

    public class Test
    {
        public static void main(String[] args)
        {
                 Class<?> c1 = null;
                 try
                 {

                       c1 = Class.forName("cn.classes.Person");

                       // 不带参数的方法调用
                       
    Method m = c1.getMethod("add");
                       m.invoke(c1.newInstance());

     

                       // 带参数方法调用
                       
    Method m1 = c1.getMethod("addWithParameters", String.class, int.class);
                       
    m1.invoke(c1.newInstance(), "xy", 22);
                }
                catch (Exception e)
                {
                       e.printStackTrace();
                }
        }
    }

     

     

    五 Class获得getter,setter方法

    Class这个类可以获得类的很多信息,比如获得该类的接口,构造函数,属性,方法等。我们来看如何获得getter,setter方法。

    package cn.classes;

    public class Person
    {
        private String name;
        private int age;

        省略getter,setter  

     }

     

    package cn.test;

    import java.lang.reflect.Method;

    public class Test
    {
        public static void main(String[] args)
        {
               Class<?> c1 = null;
               Object obj = null;
               try
               {
                         c1 = Class.forName("cn.classes.Person");
                         obj = c1.newInstance();
                         setter(obj, "name", "xy", String.class);
                         setter(obj, "age", 20, int.class);
                         getter(obj, "name");
                         getter(obj, "age");
               }
               catch (Exception e)
                {
                        e.printStackTrace();
                }
       }

       /**
        * @param obj:要操作的对象
        * @param att:要操作的属性
        * @param value:要设置的属性内容
        * @param type:要设置的属性类型
        */
        public static void setter(Object obj, String att, Object value, Class<?> type)
        {
             try
             {
                // 得到setter方法
              Method m = obj.getClass().getMethod("set" + initStr(att), type);
              m.invoke(obj, value);
             }
             catch (Exception e)
             {
              e.printStackTrace();
             }
       }

       /**
        * @param obj:要操作的对象
        * @param att:要操作的属性
        */
       public static void getter(Object obj, String att)
       {
            try
            {
                   // 得到getter方法
                   Method m = obj.getClass().getMethod("get" + initStr(att));
                   System.out.println(m.invoke(obj));
            }
           catch (Exception e)
           {
                   e.printStackTrace();
           }
       }

       public static String initStr(String oldStr)
       {
             String newStr = oldStr.substring(0, 1).toUpperCase() + oldStr.substring(1);
             return newStr;
       }
    }

     

    六 Spring调用getter,setter方法

    我们以setter注入例子

    bean.xml
    <bean id="id" class="com.xy.Student">
        
    <property name="stuName" value="xy" />
    </bean>


    Spring将采用的代码创建代码Java实例,并注入值:
    Class c = Class.forName("com.xy.Student");
    Object bean = c.newInstance();


    通过一些操作获取对stuName对应的setter方法名
    String setname = "set" + "StuName";
    Method method = c.getMehod(setname,String.Class);
    method.invoke(bean,"xy");

    这样就完成了最基本的注入操作。当然,Spring还可以通过构造函数进行注入。这样就参考第二点有参构造的Class的使用。

    Class还可以访问Annotation,这样就Spring使用注解的时候,可以完成注入的功能。

     

    七 总结

    反射的内容还是很多的,需要系统的学习。当然,Spring也是。


    转载来源:http://blog.csdn.net/asdfsadfasdfsa/article/details/53930798

    展开全文
  • Class&lt;?&gt; cls = Class.forName("...); // 取得Class对象 传入一个包名+类名的字符串就可以得到Class... Object obj = cls.newInstance() //反射实例化对象 Constructor&lt;?&gt; cons = c...

    Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象 传入一个包名+类名的字符串就可以得到Class对象

     

    第一步:获得对象,构造方法,普通方法,属性

      Object obj = cls.newInstance() //反射实例化对象
      Constructor<?> cons = cls.getConstructor(String.class, int.class);//获得构造方法
      Method m3 = cls.getDeclaredMethod("getName"); //获得get方法
      Field nameField = cls.getDeclaredField("name"); // 获得name属性
    第二步:获得之后---如何用的问题

    复制代码

    1.    虽然用此方法创造的对象比new出来的复杂,但是有利于程序的解耦,增加扩展性
            8/22框架技术都是通过此技术进行解耦操作的
    2.      Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
            Constructor<?> cons = cls.getConstructor(String.class, int.class);
            Object obj = cons.newInstance("张三", 20); // 为构造方法传递参数
            System.out.println(obj); // Person [name=张三, age=20]
    
    3.    Method m = cls.getDeclaredMethod("say");   //say是自己在类中自定义的方法
            m.invoke(obj);//输出123456789,这个obj可以是new出来的或newInstance出来的
    
    4.      Object obj = Class.forName("Person").newInstance();
            Field nameField = cls.getDeclaredField("name"); // 获得name属性
            nameField.setAccessible(true); //解除封装
            nameField.set(obj, "张三"); // Person对象.name = "张三"
            System.out.println(nameField.get(obj)); // Person对象.name

    复制代码

     

    9/3日再学习

    servlet MVC框架的老祖宗


     
    反射之中包含了一个“反”的概念,所以要想解释反射就必须先从“正”开始解释,一般而言,当用户使用一个类的时候,应该先知道这个类,而后通过这个类产生实例化对象,但是“反”指的是通过对象找到类。
    packagecn.mldn.demo;
    classPerson {}
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Person per = new Person() ; // 正着操作-由类到对象
    System.out.println(per.getClass().getName()); // 反着来-由对象到类
    }
    }
    

     

    以上的代码使用了一个getClass()方法,而后就可以得到对象所在的“包.类”名称,这就属于“反”了,但是在这个“反”的操作之中有一个getClass()就作为发起一切反射操作的开端。

    Person的父类是Object类,而上面所使用getClass()方法就是Object类之中所定义的方法。

    ·取得Class对象:public final Class<?> getClass()反射之中的所有泛型都定义为?,返回值都是Object

    而这个getClass()方法返回的对象是Class类的对象,所以这个Class就是所有反射操作的源头。但是在讲解其真正使用之前还有一个需要先解释的问题,既然Class是所有反射操作的源头,那么这个类肯定是最为重要的,而如果要想取得这个类的实例化对象,Java中定义了三种方式:

    方式一:通过Object类的getClass()方法取得,基本不用:

    packagecn.mldn.demo;
    classPerson {}
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Person per = newPerson() ; // 正着操作
    Class<?> cls = per.getClass() ; // 取得Class对象
    System.out.println(cls.getName()); // 反着来
    }
    }
    

     

    方式二:使用“类.class”取得,在日后学习Hibernate开发的时候使用

    packagecn.mldn.demo;
    classPerson {}
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Person.class; // 取得Class对象
    System.out.println(cls.getName()); // 反着来
    }
    }
    

     

    方式三:使用Class类内部定义的一个static方法,主要使用

    ·取得Class类对象:public static Class<?> forName(String className) throws ClassNotFoundException

    packagecn.mldn.demo;
    classPerson {}
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
    System.out.println(cls.getName()); // 反着来
    }
    }
    

     

    那么现在一个新的问题又来了,取得了Class类的对象有什么用处呢?对于对象的实例化操作之前一直依靠构造方法和关键字new完成,可是有了Class类对象之后,现在又提供了另外一种对象的实例化方法:

    ·通过反射实例化对象(通过new实例化对象):public T newInstance() throws InstantiationException, IllegalAccessException




     

    范例:通过反射实例化对象,实例化出的这个对象就可以调用类里面的方法和属性

    packagecn.mldn.demo;
    classPerson {
    @Override
    publicString toString() {
    return"Person Class Instance .";
    }
    }
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
    Object obj = cls.newInstance() ; // 实例化对象,和使用关键字new一样
    Person per = (Person) obj ; // 向下转型
    System.out.println(per);
    }
    }
    

     

    那么现在可以发现,对于对象的实例化操作,除了使用关键字new实例化对象之外又多了一个反射机制操作,而且这个操作要比之前使用的new复杂一些,可是有什么用?

    对于程序的开发模式之前一直强调:尽量减少耦合,而减少耦合的最好做法是使用接口,但是就算使用了接口也逃不出关键字new,所以实际上new是造成耦合的关键元凶。

    范例:回顾一下之前所编写的工厂设计模式

    packagecn.mldn.demo;
    interface  Fruit {
    public  void  eat() ;
    }
    classApple  implements  Fruit {
    public  void  eat() {
    System.out.println("吃苹果。");
    };
    }
    class  Factory {
    public  static  Fruit getInstance(String className) {
    if("apple".equals(className)){
    return  new  Apple() ;
    }
    returnnull;
    }
    }
    publicclassFactoryDemo {
    publicstaticvoidmain(String[] args) {
    Fruit f = Factory.getInstance("apple") ;  //静态方法
    f.eat() ;
    }
    }
    

     

    以上为之前所编写最简单的工厂设计模式,但是在这个工厂设计模式之中有一个最大的问题:如果现在接口的子类增加了,那么工厂类肯定需要修改,这是它所面临的最大问题,而这个最大问题造成的关键性的病因是new,那么如果说现在不使用关键字new了,变为了反射机制呢?

    反射机制实例化对象的时候实际上只需要“包.类”就可以,于是根据此操作,修改工厂设计模式。

    packagecn.mldn.demo;
    interfaceFruit {
    publicvoideat() ;
    }
    classApple implementsFruit {
    publicvoideat() {
    System.out.println("吃苹果。");
    };
    }
    classOrange implementsFruit {
    publicvoideat() {
    System.out.println("吃橘子。");
    };
    }
    classFactory {
    publicstaticFruit getInstance(String className) {
    Fruit f = null;
    try{
    f = (Fruit) Class.forName(className).newInstance() ;
    //获得Class对象----实例化一个类的对象
    } catch(Exception e) {
    e.printStackTrace();
    }
    returnf ;
    }
    }
    publicclassFactoryDemo {
    publicstaticvoidmain(String[] args) {
    Fruit f = Factory.getInstance("cn.mldn.demo.Orange") ;
    //只要传入字符串进入就可以实例化对象--深度解耦了
    f.eat() ;
    }
    }
    

     

    发现,这个时候即使增加了接口的子类,工厂类照样可以完成对象的实例化操作,这个才是真正的工厂类,可以应对于所有的变化。如果单独从开发角度而言,与开发者关系不大,但是对于日后学习的一些框架技术这个就是它实现的命脉在日后的程序开发上,如果发现操作的过程之中需要参数传递了一个完整的“包.类”名称的时候几乎都是反射机制作用。

     

    8.22在此做笔记

    向上塑性的好处是,增加extensible,
    要是接口的实现类B换成了实现类c,照样可以用A的引用变量.say()
    在上面的类中,增加一个草莓类,但是工程这个类可以在不修改的情况下继续使用
    这边进行了增加或者删除,不用修改 另外一边,降低了耦合度,增加了可扩展性

     

     

    8/21日在次做笔记深入理解

    开发中用到的bean工厂,传入一个字符串就获得相应的对象

     




     

    3.12.2 、反射的深入应用

    以上只是利用了Class类作为了反射实例化对象的基本应用,但是对于一个实例化对象而言,它需要调用类之中的构造方法、普通方法、属性,而这些操作都可以通过反射机制完成。

     

    3.12.2 .1、调用构造

    反射获得构造方法cons,cls是Class类型的对象

    Constructor<?> cons = cls.getConstructor(String.class, int.class);

    Object obj = cons.newInstance("张三", 20); //获得了这个构造如何用? 为构造方法传递参数

    class类里面的提供构造方法

     

    使用反射机制也可以取得类之中的构造方法,这个方法在Class类之中已经明确定义了:

    以下两个方法

    取得一个类的全部构造:

    public Constructor<?>[] getConstructors() throws SecurityException

    取得一个类的指定参数构造:

    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

     

    现在发现以上的两个方法返回的都是java.lang.reflect.Constructor类的对象。

    范例:取得一个类之中的全部构造

    packagecn.mldn.demo;
    importjava.lang.reflect.Constructor; //不在java语言包
    classPerson { // CTRL + K
    publicPerson() {}
    publicPerson(String name) {}
    publicPerson(String name,intage) {}
    }
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
    Constructor<?> cons [] = cls.getConstructors() ; // 取得全部构造
    for(intx = 0; x < cons.length; x++) {
    System.out.println(cons[x]);
    }
    }
    }
    

     

    验证:在之前强调的一个简单Java类必须存在一个无参构造方法

    范例:观察没有无参构造的情况

    packagecn.mldn.demo;
    classPerson { // CTRL + K
    privateString name;
    privateintage;
    publicPerson(String name,intage) {
    this.name= name ;
    this.age= age ;
    }
    @Override
    publicString toString() {
    return"Person [name="+ name+ ", age="+ age+ "]";
    }
    }
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
    Object obj = cls.newInstance(); // 实例化对象
    System.out.println(obj);
    }
    }
    

     /*在进行spring开发的时候看见---进行构造器注入的时候,若提供了有参的构造方法

    则无参数的构造方法必须人为提供,否则系统不会自动提供

    */

    此时程序运行的时候出现了错误提示“java.lang.InstantiationException”,因为以上的方式使用反射实例化对象时需要的是类之中要提供无参构造方法,但是现在既然没有了无参构造方法,那么就必须明确的找到一个构造方法,而后利用Constructor类之中的新方法实例化对象:

    ·实例化对象:public T newInstance(Object... initargs) throws InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException

    复制代码

    package cn.mldn.demo;
    
    import java.lang.reflect.Constructor;
    
    class Person { // CTRL + K
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public Person() {
        }
            
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
        public void say(){
            System.out.println("hi");
        }
    }
    
    public class TestDemo {
        public static void main(String[] args) throws Exception {
            Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
            // 取得指定参数类型的构造方法
            Constructor<?> cons = cls.getConstructor(String.class, int.class);
            Object obj = cons.newInstance("张三", 20); // 为构造方法传递参数
            System.out.println(obj); // Person [name=张三, age=20]
            Object obj1 = cls.newInstance();//里面不能使用传统的构造函数的装入newInstance("张三", 20)
            Person I = (Person)obj; 
            I.say();// hi
        }
    }

    复制代码

    很明显,调用无参构造方法实例化对象要比调用有参构造的更加简单、方便,所以在日后的所有开发之中,凡是有简单Java类出现的地方,都一定要提供无参构造。




     

    3.12.2 .2、调用普通方法

    Class类下面的2个方法

     

    当取得了一个类实例化对象之后,下面最需要调用的肯定是类之中的方法,所以可以继续使用Class类取得一个类中所定义的方法定义:

    ·取得全部方法:public Method[] getMethods() throws SecurityException

    ·取得指定方法:public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

    发现以上的方法返回的都是java.lang.reflect.Method类的对象。

    范例:取得一个类之中所定义的全部方法

    packagecn.mldn.demo;
    importjava.lang.reflect.Method;
    classPerson {
    privateString name;
    publicvoidsetName(String name) {
    this.name= name;
    }
    publicString getName() {
    returnname;
    }
    }
    publicclassTestDemo {
    publicstaticvoidmain(String[] args) throwsException {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
    Method met [] = cls.getMethods() ; // 取得全部方法
    for(intx = 0; x < met.length; x++) {
    System.out.println(met[x]);
    }
    }
    }
    

     

    但是取得了Method类对象最大的作用不再于方法的列出(方法的列出都在开发工具上使用了),但是对于取得了Method类对象之后还有一个最大的功能,就是可以利用反射调用类中的方法:

    ·调用方法:public Object invoke(Object obj, Object... args) throws IllegalAccessException,IllegalArgumentException, InvocationTargetException

    之前调用类中方法的时候使用的都是“对象.方法”,但是现在有了反射之后,可以直接利用Object类调用指定子类的操作方法。(同时解释一下,为什么settergetter方法的命名要求如此严格)。

     

    范例:利用反射调用Person类之中的setName()getName()方法

     

    复制代码

    package cn.mldn.demo;
    
    import java.lang.reflect.Method;
    
    class Person {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
        public void say(){
            System.out.println(123456789);
        }
    }
    
    public class TestDemo {
        public static <Mehtod> void main(String[] args) throws Exception {
            Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
            Object obj = cls.newInstance(); // 实例化对象,没有向Person转型
            String attribute = "name"; // 要调用类之中的属性
            Method setMet = cls.getMethod("set" + initcap(attribute), String.class);// setName()
            Method getMet = cls.getMethod("get" + initcap(attribute));// getName()
            setMet.invoke(obj, "张三"); // 等价于:Person对象.setName("张三")
            System.out.println(getMet.invoke(obj));// 等价于:Person对象.getName() 输出张三
            /*自己测试-------------------------------------------------*/
            Person p =(Person)obj;
            p.say();//输出123456789
            Method m = cls.getDeclaredMethod("say");
            m.invoke(obj);//输出123456789
            /*自己测试-------------------------------------------------*/
            Method m2 = cls.getDeclaredMethod("setName", String.class);//获得了set方法 
            Method m3 = cls.getDeclaredMethod("getName"); //get方法
            m2.invoke(obj, "张三");//如何用
            System.out.println(m3.invoke(obj)); // 张三    
        }
    
        public static String initcap(String str) {
            return str.substring(0, 1).toUpperCase().concat(str.substring(1));
        }
    }

    复制代码

     

     

    在日后的所有框架技术开发之中,简单Java类都是如此应用的,所以必须按照标准进行。

     




     

    3.12.2 .3、调用成员

    Class类里面的方法

     

    类之中最后一个组成部分就是成员(Field,也可以称为属性),如果要通过反射取得类的成员可以使用方法如下:

    ·取得本类的全部成员:public Field[] getDeclaredFields() throws SecurityException

    ·取得指定的成员:public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException

    这两个方法的返回值类型是java.lang.reflect.Field类的对象,下面首先观察如何取得一个类之中的全部属性。

    范例:取得一个类之中的全部属性

    packagecn.mldn.demo;
    importjava.lang.reflect.Field;
    classPerson {
    privateString name;
    }
    public  class  TestDemo {
    public  static  void  main(String[] args) throws Exception {
    Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 第一步:取得Class对象
    Field field [] = cls.getDeclaredFields() ; // 第二步:取得全部属性
    for(intx = 0; x < field.length; x++) {
    System.out.println(field[x]);
    }
    }
    }
    

     

    但是找到Field实际上就找到了一个很有意思的操作,在Field类之中提供了两个方法:

    ·设置属性内容(类似于:对象.属性内容):public void set(Object obj, Object value)

    throws IllegalArgumentException, IllegalAccessException

    ·取得属性内容(类似于:对象.属性):public Object get(Object obj)

    throws IllegalArgumentException, IllegalAccessException

    可是从类的开发要求而言,一直都强调类之中的属性必须封装,所以现在调用之前要想办法解除封装。

    ·解除封装:public void setAccessible(boolean flag) throws SecurityException

    范例:利用反射操作类中的属性

    复制代码

    import java.lang.reflect.Field;
    
    class Person {
        private String name;
        int age = 88;
    
        public void say() {
            System.out.println(123456789);
        }
    }
    
    public class TestDemo {
        public static void main(String[] args) throws Exception {
            Class<?> cls = Class.forName("Person"); // 取得Class对象
            Object obj = cls.newInstance(); // 对象实例化(不通过new--obj和以前的new出来的对象用法一样)属性才会分配空间
            Field nameField = cls.getDeclaredField("name"); // 获得name属性
            nameField.setAccessible(true); // 如何用解除封装了
            nameField.set(obj, "张三"); // Person对象.name = "张三"
            System.out.println(nameField.get(obj)); // Person对象.name
            /*如果里面有get方法,可以通过obj.getName()获得这个属性*/
            /*证明通过反射获得类的对象和以前new出来的是一样的*/
            Person pp = (Person) obj;
            pp.age = 99;
            System.out.println(pp.age);
            pp.say();
        }
    }
    

     

    复制代码

     资料来源:经过加工整理

    展开全文
  • java 利用反射实例化类对象

    千次阅读 2014-10-04 10:06:22
    * java 使用反射实例化一个对象 * 第一种方式:创建类类对象,调用类类对象的newInatance方法获取要实例化的的对象,然后调用对象的setter方法设置属性。 * 第二种方式:使用类类对象的getConatructor方法...
  • 所以保证了枚举不会被反射实例化 另外,序列化一个枚举的对象,获取的时候调用的是继承的Enum的valueOf 方法T result = enumType.enumConstantDirectory().get(name);根据name去找存入的对象,所以不会生成多个...
  • 实现的功能的业务是这样的,动态的获取java接口的所有的实现并且排除抽象和接口本身。 代码实现 1.创建接口Animal package com.tcp.executor; public interface Animal { public void say(); } 2.创建抽象...
  • 原文地址: https://blog.unlink.link/php/php_runtime_instance_class_and_pass_parameters.html/comment-page-1 ...什么是动态实例化对象呢?我们先来看一下PHP有一种变量函数(可变函数)的概念,例如如
  • 调用的,在源包single,代码如下: /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template ...
  • [超级通道 : Java反射学习系列-绪论] 1.Class对象获取的三种方式 上一章节已经说过,一般情况下,Java反射操作都需要首先获取Class对象。获取Class对象的方式有三种。 公有属性class 方法getClass() Class.for...
  •   反射是Java中至关重要的一个概念,我们必须要对它进行掌握。 1. 反射概念   反射指的是对对象的反向处理... 我们想要创建Date的对象实例化,首先要引入定义Data的包 import java.util.Date; public...
  • 二、这篇文章主要介绍一下通过反射机制去实例化一个的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class的newnstance()方法进行实例化,下面我就通过代码来...
  • 二、这篇文章主要介绍一下通过反射机制去实例化一个的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class的newnstance()方法进行实例化,下面我就通过代码来...
  • 实习期间遇到一个题,题目大致是...有若干行这样的数据,要求根据文件内容实例化类并且为其属性赋值,最后调用该方法,输出的各属性。 之前一直不会如何讲给定的类实例化,学习后代码如下: package com.quna...
  • 为什么要让工具不能被实例化

    千次阅读 2019-06-17 17:48:04
    首先我们知道,工具是可以实例化的,只是没有必要去实例化。 工具是为了提供一些通用的某一非业务领域内的公共方法,不需要配套的成员变量,仅仅是作为工具方法被使用。所以将它做成静态方法最合适,不需要...
  • 反射

    千次阅读 多人点赞 2019-07-14 20:30:55
    反射三大作用(java.lang.reflect.*)4.1获取对象的三种方式4.2反射实例化对象4.3 反射动态调用方法4.4 反射读写属性5.访问修饰符 1.什么是反射 反射java语言中的一种机制,通过机制可以动态的实例化对象,读写属性...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    内部的分类有哪些 静态内部 成员内部 局部内部 匿名内部 内部的优点 内部有哪些应用场景 局部内部和匿名内部访问局部变量的时候,为什么变量必须要加上final? 内部相关,看程序说出运行结果 ...
  • Java加载过程和对象实例化详解

    千次阅读 2017-11-19 17:21:28
     从被加载虚拟机内存中开始,到卸载出内存为止,他的整个生命周期包括:加载、验证、准备、解析、初始、使用和卸载。其中验证、准备、解析3个阶段统称为连接。 ![的生命周期]...
  • 准备一个,有参构造方法,字段,方法都是私有的 public class Car { private String name; private Integer age; private Car(String name, Integer age) { this.name = name; this.age = age; } ...
  • 就Spring IoC容器而言,bean定义基本上描述了创建一个或多...因此需要告知Spring IoC容器我们将要实例化的对象的类型以及如何实例化对象。 spring实例化bean的三种方式 用构造器来实例化 使用 静态工厂方法实例化 ...
  • 个人理解反射可以不通过new这个关键字产生一个指定的,并可以调用成员变量,... * 反射取得实例化对象的三种方式 * @author 76519 * */ public class TestDemo1 { public static void main(String[] args) { ...
  • java 反射实例化内部

    千次阅读 2009-12-08 16:34:00
    java 反射实例化内部原文链接 http://mysun.javaeye.com/blog/457182  内部的初始化同一般的初始化基本相同,只是内部的类名全称有些区别。下面定义了一个Outer和一个Inner: Java代码 public class...
  • private String name; public People(){ this.name = "默认名字"; } public People(String str) { name = str; } public String getName() { return name; } publ...
  • 实例化类的五种方法

    万次阅读 2018-05-15 19:26:30
    2、使用Class的newInstance方法3、使用Constructor的newInstance方法 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor的newInstance()实例方法。如:Object obj = Class.forName("...
  • C# 反射实例获取属性

    千次阅读 2016-03-30 22:45:33
    C# 反射实例获取属性定义以及属性如下public class AgentClass { public int agentID { get; private set; } public int level { get; private set; } public int bl
  • 深入理解Java对象的创建过程:的初始化与实例化

    万次阅读 多人点赞 2017-05-18 14:17:45
    实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用构造器完成的初始化。在初始化过程中或初始化完毕后,根据具体情况才会去对进行实例化。本文试图对JVM...
  • 接口 InitializerInterface.java import android.content.Context; public interface InitializerInterface { void init(Context context)...实现 LoggerInitializer.java import android.content.Context; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,720
精华内容 45,888
关键字:

反射实例化private类