反射机制2,Class类的使用

class是反射源头,不光可以取得对象所在类信息,也可直接通过class类的方法进行对象的实例化操作。

使用关键字new为对象实例化。如果已经实例化好了class对象,就可以通过class类中提供的newInstance()操作

public T newInstance()
              throws InstantiationException,
                     IllegalAccessException

来个例子:

package 类集;

class Person{
    private String name ;    // name属性
    private int age ;        // age属性
    public void setName(String name){
        this.name = name ;
    }
    public void setAge(int age){
        this.age = age ;
    }
    public String getName(){
        return this.name ;
    }
    public int getAge(){
        return this.age ;
    }
    public String toString(){    // 覆写toString()方法
        return "姓名:" + this.name + ",年龄:" + this.age  ;
    }
};
public class test1{
    public static void main(String args[]){
        Class<?> c = null ;        // 声明Class对象
        try{
            c = Class.forName("类集.Person") ;
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Person per = null ;    // 声明Person对象
        try{
            per = (Person)c.newInstance() ;    // 实例化对象
        }catch(Exception e){
            e.printStackTrace() ;
        }
        per.setName("小明") ;        // 设置姓名
        per.setAge(23) ;                // 设置年龄
        System.out.println(per) ;    // 内容输出,调用toString()
    }
}

返回结果:

姓名:小明,年龄:23

上面的newInstance返回的类型是一个泛型,但是Class<?> c可知,这个类型是一个“?”,实际上是一个object类型,

所以需要向下转型,(Person)c.newInstance()。

通过以上代码发现,即使不使用new关键字也能进行实例化操作,反射作用。

但是,使用以上操作,必须注意:在操作中,类中必须存在无参构造方法。否则无法实例化。

例如:

package 类集;

class Person{
    private String name ;    // name属性
    private int age ;        // age属性
    public Person(String name,int age){
        this.setName(name) ;
        this.setAge(age);
    }
    public void setName(String name){
        this.name = name ;
    }
    public void setAge(int age){
        this.age = age ;
    }
    public String getName(){
        return this.name ;
    }
    public int getAge(){
        return this.age ;
    }
    public String toString(){    // 覆写toString()方法
        return "姓名:" + this.name + ",年龄:" + this.age  ;
    }
};
public class test1{
    public static void main(String args[]){
        Class<?> c = null ;        // 声明Class对象
        try{
            c = Class.forName("类集.Person") ;
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Person per = null ;    // 声明Person对象
        try{
            per = (Person)c.newInstance() ;    // 实例化对象
        }catch(Exception e){
            e.printStackTrace() ;
        }
        per.setName("李兴华") ;        // 设置姓名
        per.setAge(30) ;                // 设置年龄
        System.out.println(per) ;    // 内容输出,调用toString()
    }
}

结果;

java.lang.InstantiationException: 类集.Person
    at java.lang.Class.newInstance(Class.java:427)
    at 类集.test1.main(test1.java:36)
Caused by: java.lang.NoSuchMethodException: 类集.Person.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 1 more
Exception in thread "main" java.lang.NullPointerException
    at 类集.test1.main(test1.java:40)

  所以发现,使用以上方式,实际上还是需要无参构造方法的支持。符合于对象实例化要求。(实际上跟正常实例化new 类()方式一样,调用构造方法)。

要想解决这样问题,则必须明确指定要调用的构造方法,并且传递参数。从实际开发角度,一般使用反射实例化对象的时候,类中最好存在一个无参构造,比较合理。

操作步骤如下:

1,通过class类中的getConstructors()取得本类中全部构造方法,返回的结果是一个数组,见下面例子,

2,向构造方法中传递一个对象数组进去,里面保护构造方法所需要的各个参数。

3,之后通过Constructor实例化对象。

在constructor类中存在方法newInstance(),

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

传递初始化参数,以进行对象的实例化操作。

明确调用有参构造,实例化对象。

package 类集;

import java.lang.reflect.Constructor;

class Person{
    private String name ;    // name属性
    private int age ;        // age属性
    public Person(String name,int age){
        this.setName(name) ;
        this.setAge(age);
    }
    public void setName(String name){
        this.name = name ;
    }
    public void setAge(int age){
        this.age = age ;
    }
    public String getName(){
        return this.name ;
    }
    public int getAge(){
        return this.age ;
    }
    public String toString(){    // 覆写toString()方法
        return "姓名:" + this.name + ",年龄:" + this.age  ;
    }
};
public class test1{
    public static void main(String args[]){
        Class<?> c = null ;        // 声明Class对象
        try{
            c = Class.forName("类集.Person") ;
        }catch(ClassNotFoundException e){
            e.printStackTrace() ;
        }
        Person per = null ;    // 声明Person对象
        Constructor<?> cons[] = null ;//返回的是一个数组。
        cons = c.getConstructors() ;//取得所有构造方法
        try{
            per = (Person)cons[0].newInstance("校华",18) ;    // 实例化对象,因为只有一个构造方法,所以使用第一个构造方法,也就是cons[0],通过newInstance("",“”)传给构造方法    别忘了后面还要向下转型,因为返回结果是object类型。
        }catch(Exception e){
            e.printStackTrace() ;
        }
        System.out.println(per) ;    // 内容输出,调用toString()
    }
}

运行结果:

姓名:校华,年龄:18

注意:接收的原理如下:

但是,如果要使用反射进行对象的实例化操作,最好在类中存在无参数构造

总结:

1,本周功能是class用的最多的功能,而且开发中也会经常用到的模式

2,在使用class实例化对象的时候,必须保证类中存在无参构造,否则无法使用。

3,如果要想调用有参构造进行对象的实例化操作,必须使用constructor类完成,此类表示构造方法,并通过可变参数传递要求的内容。

时间: 2024-10-11 01:53:08

反射机制2,Class类的使用的相关文章

利用反射机制,获取类的字段、方法、并实现简单调用

这篇文章是为之后要介绍Android的ICO框架做预备的,所以,如果想最近学习Android的ICO框架的同学,可以稍微看一下. 首先,简单介绍一下Java里面的反射. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 不知道这样的一段解释,你能否看懂.如果更简单的说,反射就是能够根据你给出类名实例化出一个实实在在的对象.所以,对象的实例

Android利用反射机制为实体类属性赋值

在做android项目时,有时会遇到从网络上获取json类型数据,赋值给实体类,实体类属性少可以一个一个的赋值,如果实体类有很多属性,赋值可能就要耗很长的功夫了,幸好Java给我们提供了反射机制.下面是在我在android中如何利用java反射机制给实体类赋值. 在Android中利用反射机制为实体类属性赋值,首先需要导入一下两个包 import java.lang.reflect.Field; import java.lang.reflect.Method; 给实体类赋值首先需要一个实体类,这

java反射机制取出model类的所有变量,以及value

原文:java反射机制取出model类的所有变量,以及value 源代码下载地址:http://www.zuidaima.com/share/1550463649270784.htm 工作上遇到个问题,顺便解决了,希望对大家有帮助 package com.zuidaima.util; public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAcce

Java反射机制(取得类的结构)

通过反射得到一个类中的完整的结构,就要使用java.lang.reflect包中的以下几个类: Constructor:表示类中的构造方法 Field:表示类中的属性 Method:表示类中的方法 Class类中的常用方法: 确定此对象所表示的类或接口实现的接口. public Class<?>[] getInterfaces() 取得父类 public Class<? super T> getSuperclass() 取得全部的构造方法 public Constructor<

使用java反射机制编写Student类并保存

定义Student类 1 package org; 2 3 public class Student { 4 private String _name = null; 5 private int _age = -1; 6 private int _score = -1; 7 8 public Student() 9 { 10 11 } 12 13 public Student(String name, int age, int score) 14 { 15 _name = name; 16 _a

Java反射机制(Class类的使用)

1:通过无参构造实例化对象 package cn.itcast; /* * 通过无参构造实例化对象 * 通过Class类本身实例化对象,使用newInstance方法 * 需要注意的是:实例化类中存在一个无参构造的方法,如果不存在将无法实例化Person对象: * 如果没有则报异常:InstantionException * */ public class ClassDemo03 { public static void main(String[] args) { //创建Class对象 Cla

反射机制--获取类的方法

一.反射机制获取一个类的方法 1.使用class属性 类名.class 2.使用Class类的forName("类名")方法, Class.forName("类名") 3.new一个类然后调getClass()方法 new 类名().getClass() 实例: public void text() throws ClassNotFoundException{ //第一种方式 Class cla = Integer.class; //第二种方式 Class cla2

Java反射机制demo(四)—获取一个类的父类和实现的接口

Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 Object 类.一个接口.一个基本类型或 void,则返回 null.如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象. 测试代码: package com.aaron.reflect; public class Demo4 { public static void

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性: 通过反射机制可以获得类的属性,获得到的属性同样的可以进行赋值.得值操作,调用getField方法并传递属性的名称可以获得[学Java,到凯哥学堂kaige123.com]指定的属性,调用getFields方法则可以获得全部属性,但是这种方式不能获得私有属性: 代码示例: Student类示例: 运行结果: 从运行结果可以看出只拿出了公开的属性,私有的属性拿不到. 使用反射机制调用私有成员: 1.调用私有属性 在反射机制里调用私有属性需要通过getDeclaredField

Java的反射机制简述

反射机制是Java语言中一个非常重要的特性,它允许程序在运行时进行自我检查,同时也允许内部的成员进行操作.虽然这个特性在实际开发中使用的不多,但是像Pascal.C和C++等语言根本没有提供这样的特性.由于反射机制能够实现在运行时对类进行装载,因此能够增加程序的灵活性,但是不恰当地使用反射机制也会严重影响系统的性能. 具体而言,反射机制提供的功能主要有: 1.得到一个对象所属的类: 2.获取一个类的所有成员变量和方法: 3.在运行时创建对象: 4.在运行时调用对象的方法. 其实,反射机制非常重要