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类完成,此类表示构造方法,并通过可变参数传递要求的内容。

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

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

    在做android项目时,有时会遇到从网络上获取json类型数据,赋值给实体类,实体类属性少可以一个一个的赋值,如果实体类有很多属性,赋值可能就要耗很长的功夫了,幸好Java给我们提供了反射机制.下面 ...

  2. java 通过反射机制调用某个类的方法

    package net.xsoftlab.baike; import java.lang.reflect.Method; public class TestReflect {     public s ...

  3. 利用Java反射机制对实体类的常用操作工具类ObjectUtil

    代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...

  4. 浅谈Java反射机制 之 使用类的 属性、方法和构造函数

    前面两篇我们总结了Java反射机制如何获取类的字节码,如何获取构造函数,属性和方法, 这篇我们将进一步验证如何使用我们获取到的属性.方法以及构造函数 1.使用 反射 获取到的 属性 import ja ...

  5. Day14_82_反射机制输出整个类

    利用反射机制输出整个类 代码实例 import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Ref ...

  6. c#反射机制判断同一个类的两个实例的值是否完全一样

    ; i < properties1.Length; i++)            {                string s = properties1[i].DeclaringTyp ...

  7. JAVA反射机制教程-获取类对象

    1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...

  8. 浅谈Java反射机制 之 获取类的字节码文件 Class.forName("全路径名") 、getClass()、class

    另一个篇:获取 类 的 方法 和 属性(包括构造函数) 先贴上Java反射机制的概念: AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它 ...

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

    通过反射得到一个类中的完整的结构,就要使用java.lang.reflect包中的以下几个类:   Constructor:表示类中的构造方法 Field:表示类中的属性 Method:表示类中的方法 ...

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

    定义Student类 package org; public class Student { private String _name = null; ; ; public Student() { } ...

随机推荐

  1. Hive 空指针(NPE)异常

    空指针NullPointerException 1 Hive之前的一些BUG [HIVE-9430] - NullPointerException on ALTER TABLE ADD PARTITI ...

  2. 对有些反编译不成功的apk,请更新最新的apktool.jar、 dex2jar试试

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 对有些反编译不成功的apk,请更新最新的apktool.jar. dex2jar试试 a ...

  3. 又见Python<3>:Pandas之Series对象的使用

    Pandas是Python下最强大的数据分析和探索库,是基于Numpy库构建的,支持类似SQL的结构化数据的增.删.查.改,具有丰富的数据处理函数.Pandas有两大数据结构:Series和DataF ...

  4. bzoj 4412: [Usaco2016 Feb]Circular Barn

    4412: [Usaco2016 Feb]Circular Barn Description 有一个N个点的环,相邻两个点距离是1.点顺时针标号为1..N.每一个点有ci头牛,保证∑ci=N.每头牛都 ...

  5. Java学习笔记(7)

    构造函数: 构造函数的作用:给对应的对象进行初始化. 构造函数定义的格式: 修饰符   函数名(形式参数){ 函数体... } 构造函数要注意的细节: 构造函数是没有返回值类型的 构造函数的函数名必须 ...

  6. MyBatis 显示日志

    <!-- 全局配置 --> <settings> <setting name="cacheEnabled" value="false&quo ...

  7. git log --oneline --graph的读法

    星号表明这个提交所在的分支: 最左边的直线表示当前分支的历史状态,从图看,当前分支HEAD是master分支 :提交历史是:8cfbb25<--d486463<--a88c595<- ...

  8. 如何解决sqlmapapi重启后,任务全部丢失的问题

    sqlmapapi的server每次启动时都会创建一个新的数据库,这样之前的扫描记录都会全部丢失 使用python sqlmapapi.py -s可以看大IPC database的位置,这个各个操作系 ...

  9. Linux 调度器发展简述

    引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的 ...

  10. scrapy-splash抓取动态数据例子二

    一.介绍 本例子用scrapy-splash抓取一点资讯网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...