文档章节

Java中创建对象的几种方法

空净
 空净
发布于 2017/05/03 16:37
字数 1099
阅读 53
收藏 0

概况

据我所知,Java创建对象有以下几种方法:

  1. 使用new关键字
  2. 使用Class类的newInstance方法
  3. 使用Constructor类的newInstance方法
  4. 使用Clone的方法
  5. 使用反序列化

下面我们来一一练习。

获取类的位置和名称

package 获取类的位置和名称;

import pojo.Person;

public class GetClassName {
	public static void main(String[] args) {
        Class<?> demo2=null;
        Class<?> demo3=null;
        //方式1
        demo2=new Person().getClass();
        
        //方式2
        demo3=Person.class;
        
        System.out.println("类名称   "+demo2.getName());
        System.out.println("类名称   "+demo3.getName());
    }
}

Class类

package 无参数反射;

import pojo.Person;

public class TestClassNewInstance {
	public static void main(String[] args) {
		//想反射创建对象,首先我们需要知道类的位置和名称
		//这句话获取类的包名和类名
		String p=Person.class.getName();
		System.out.println("对象的包名+类名:"+p);
		
		 Class<?> demo=null;
	       try{
	           demo=Class.forName(p);
	          /*
	           * 笔记:
	           * Class.forName(xxx.xx.xx) 返回的是一个类 
	           * 作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
	           * 
	           * 从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。
	           * 但是使用newInstance()方法的时候,就必须保证:
	           * 1、这个类已经加载;
	           * 2、这个类已经连接了。
	           * 而完成上面两个步骤的正是Class的静态方法forName()所完成的,
	           * 这个静态方法调用了启动类加载器,即加载java API的那个加载器。 
	           * 
	           * 
	           * newInstance: 弱类型。低效率。
	           * new: 强类型。相对高效。能调用任何public构造。
	           */
	           
	       }catch (Exception e) {
	           e.printStackTrace();
	       }
	       Person per=null;
	       try {
	    	   //下面的“(Person)”可以换成demo实现的接口
	           per=(Person)demo.newInstance();
	       } catch (InstantiationException e) {
	           e.printStackTrace();
	       } catch (IllegalAccessException e) {
	           e.printStackTrace();
	       }
	       per.setName("周星驰");
	       per.setAge(20);
	       System.out.println(per);
	}

}
package 有参数反射;

import java.lang.reflect.Constructor;

import pojo.User;

public class ClassNewInstance {
	public static void main(String[] args) {
		// 这句话获取类的包名和类名
		String p = User.class.getName();
		Class<?> demo = null;
		try {
			demo = Class.forName(p);
		} catch (Exception e) {
			e.printStackTrace();
		}
		User per0 = null;
		User per1 = null;
		User per2 = null;
		User per3 = null;
		User per4 = null;
		// 取得全部的构造函数
		Constructor<?> cons[] = demo.getConstructors();
		System.out.println(cons.length);

		try {
			// 默认的构造函数的下标最大,User一个有五个构造函数,所以默认构造函数的下标为4
			per0 = (User) cons[4].newInstance();
			// 构造函数1
			per1 = (User) cons[0].newInstance("Rollen");
			// 构造函数2
			per2 = (User) cons[1].newInstance(20);
			// 构造函数3
			per3 = (User) cons[2].newInstance("Rollen", "周星星");
			// 构造函数4
			per4 = (User) cons[3].newInstance("Rollen", 20, "周星星");

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(per0);
		System.out.println(per1);
		System.out.println(per2);
		System.out.println(per3);
		System.out.println(per4);
	}

}

Constructor类

package 有参数反射;

import java.lang.reflect.Constructor;

import pojo.User;

public class ConstructorNewInstance {
	/*
	 * newInstance() 的参数版本与无参数版本详解
	 * 
	 * 通过反射创建新的类示例,有两种方式: Class.newInstance() Constructor.newInstance()
	 * 
	 * 以下对两种调用方式给以比较说明: Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;
	 * Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。
	 * 
	 * Class.newInstance() 抛出所有由被调用构造函数抛出的异常。
	 * 
	 * Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的;
	 * Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。
	 */

	public static void main(String[] args) {
		String className = User.class.getName();
		try {
			/* 可以使用相对路径,同一个包中可以不用带包路径 */
			Class<?> c = Class.forName(className);
			/* 以下调用无参的、私有构造函数 */
			Constructor<?> con1 = c.getDeclaredConstructor();
			/*
			 * 笔记: 在类的外面获取此类的私有成员变量的value时 将此对象的 accessible 标志设置为指示的布尔值。 值为 true
			 * 则指示反射的对象在使用时应该取消 Java 语言访问检查。 值为 false 则指示反射的对象应该实施 Java 语言访问检查。
			 * 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
			 * 
			 * 
			 * 如果有private修饰,默认accessible为false,则会报错
			 * java.lang.IllegalAccessException: Class
			 * 有参数反射.ConstructorNewInstance can not access a member of class
			 * pojo.User with modifiers "private"at
			 * sun.reflect.Reflection.ensureMemberAccess(Unknown Source)at
			 * java.lang.reflect.Constructor.newInstance(Unknown Source)at
			 * 有参数反射.ConstructorNewInstance.main(ConstructorNewInstance.java:42)
			 */
			con1.setAccessible(true);
			User user01 = (User) con1.newInstance();
			/* 以下调用带参的、私有构造函数 */
			Constructor<?> con2 = c.getDeclaredConstructor(new Class[] {
					String.class, String.class });
			con2.setAccessible(true);
			User user02 = (User) con2
					.newInstance(new Object[] { "jevon", "李叔叔" });

			System.out.println("调用无参的:" + user01);
			System.out.println("调用带参的:" + user02);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Clone方法

Person p = new Person(23, "zhang");  
Person p1 = p;  
  
System.out.println(p);  
System.out.println(p1); 

深入研究参考博客:http://blog.csdn.net/u011679955/article/details/52736379

反序列化

参考博客:

http://www.cnblogs.com/fuck1/p/5462052.html

http://blog.csdn.net/wangloveall/article/details/7992448/

 

© 著作权归作者所有

共有 人打赏支持
空净
粉丝 1
博文 31
码字总数 25970
作品 0
广州
程序员
私信 提问
Android———利用JDBC连接服务器数据库

1、Android平台下与服务器数据库通信的方法 在Android平台下,连接电脑服务器的MySQL、PostgreSQL、Oracle、Sybase、Microsoft SQLServer等数据库管理系统DBMS(database management system),...

xiahuawuyu
2012/10/10
0
1
Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结

一,java开发中: java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因:JVM内存过小、程序不严密,产生了过多的垃圾。 导致OutOfMemory...

今日竹石
2014/04/17
0
0
线上应用故障排查之二:高内存占用

搞Java开发的,经常会碰到下面两种异常: 1、java.lang.OutOfMemoryError: PermGen space 2、java.lang.OutOfMemoryError: Java heap space 要详细解释这两种异常,需要简单重提下Java内存模...

MZHS
2015/11/13
0
0
【转】115个Java面试题和答案——终极列表

本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力。下面的章节分为上下两篇,第一篇将要讨论面向对象编程和它的特点,关于Jav...

一只死笨死笨的猪
2014/09/30
0
0
Java finalize方法

《JAVA编程思想》: java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。 (1).对象不一定会被回收。 (2).垃圾回收不是析构函数。 (3).垃圾回收只与内存有关。 (4)....

清风伴月
2017/10/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式事务解决方案框架(LCN)

什么是XA接口 XA是一个分布式事务协议,由Tuxedo提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口...

群星纪元
10分钟前
0
0
linux 操作系统 常用命令和软件安装

1.系统时间更新 ntpdate time.windows.com 2.传送文件 rsync -av /home/data/a.dat -e ssh root@192.168.0.100:/home 3.传送文件夹 scp -r /home/data root@192.168.0.100:/home 4.JDK安装 ......

WJtiny
32分钟前
0
0
pg_lightool基于basebackup的单表恢复和块恢复

开源软件pg_lightool,实现了基于wal日志的块恢复。详情参见博客:https://my.oschina.net/lcc1990/blog/1931485。由于wal日志中FPW的不确定性,它不能作为一个数据库恢复的解决方案。目前对...

movead
40分钟前
2
0
对比剖析Swarm Kubernetes Marathon编排引擎

Docker Native Orchestration 基本结构 Docker Engine 1.12 集成了原生的编排引擎,用以替换了之前独立的Docker Swarm项目。Docker原生集群(Swarm)同时包括了(Docker Engine \/ Daemons)...

Linux就该这么学
41分钟前
2
0
Mybatis的结果集处理

此时我们已经可以把整段的SQL语句取出,但还并没有在数据库中去执行,我们可以先来分析一下配置文件中SQL语句执行后的结果集是如何处理的。 Mybatis会将结果集按照映射配置文件中定义的映射规...

算法之名
53分钟前
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部