从头认识java-13.9 隐式和显示的创建类型实例

对于上一章节擦除引起的问题与解决的方法有读者提出过于简单。这里解释一下:由于笔者本身也遇不到对应的问题。仅仅是凭空想像一些有可能的问题,基于水平有限,因此上一章节写的比較简单,欢迎广大读者踊跃提意见,我会尽量改进。

回归到这一章节,这里我们将讨论隐式和显示的创建类型实例。

1.隐式建类型实例

我们上一章节提到以下有问题的代码:

package com.ray.ch11;

public class Test<T> {
	public void test(Object object){
//		System.out.println(object instanceof T);//error
//		System.out.println(new T());//error
//		System.out.println(new T[10]);//error
		System.out.println((T)object );//waring
	}
}

解决办法就是以下的代码:

package com.ray.ch11;

import java.lang.reflect.Array;

public class Test<T> {
	private Class<T> kind;

	public Test(Class<T> t) {
		kind = t;
	}

	public void test(Object object) {
		System.out.println(kind.isInstance(object));
		try {
			System.out.println(kind.newInstance());
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		System.out.println(Array.newInstance(kind, 10));
		System.out.println((T) object);// waring
	}
}

可是,表面上没有太大的问题,由于我们是基于这个类有默认的构造器,我们来看看以下的代码:

package com.ray.ch11;

public class Test<T> {
	private Class<T> kind;

	public Test(Class<T> t) {
		kind = t;
	}

	public void test() {
		try {
			System.out.println(kind.newInstance());
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new Test<Integer>(Integer.class).test();
	}
}

输出:

java.lang.InstantiationException: java.lang.Integer
 at java.lang.Class.newInstance0(Class.java:340)
 at java.lang.Class.newInstance(Class.java:308)
 at com.ray.ch11.Test.test(Test.java:12)
 at com.ray.ch11.Test.main(Test.java:21)

我们降低了一些代码,可是主体还留着。然后我们在里面放上Integer这个类,我们能够从输出那里看见,直接报错。原因是Integer没有默认的构造函数。

因为上面出现的问题,因此我们推荐以下显示创建类型对象的方式。

2.显示的创建类型实例

(1)利用工厂对象来约束实现

package com.ray.ch11;

public class Test<T> {

	public static void main(String[] args) {
		new IntegerFactory().create();
	}
}

interface IFactory<T> {
	T create();
}

class IntegerFactory implements IFactory<Integer> {
	@Override
	public Integer create() {
		return new Integer(0);
	}
}

(2)通过模版方法设计模式来约束实现

package com.ray.ch11;

public class Test<T> {

	public static void main(String[] args) {
		new IntegerFactory().show();
	}
}

abstract class AFactory<T> {
	public final T obj;

	public AFactory() {
		obj = create();
	}

	abstract public T create();
}

class IntegerFactory extends AFactory<Integer> {

	@Override
	public Integer create() {
		return new Integer(0);
	}

	public void show() {
		System.out.println(obj.getClass().getName());
	}
}

总结:这一章节主要讲述隐式创建类型实例隐含的问题,以及如何通过 显示创建类型实例的解决方式。

这一章节就到这里,谢谢。

-----------------------------------

文件夹

时间: 2024-10-26 20:51:24

从头认识java-13.9 隐式和显示的创建类型实例的相关文章

JAVA 类型转换:隐式转换与强制转换

  这篇随笔是对java类型转换的回顾,方便忘记的时候查询,同时希望帮助有这方面需要的朋友 一. 数据类型分类: 简单数据类型:整型.实型.字符型((byte-short-char)-int-long-float-double) 二.简单类型转换 (1)低级向高级转换---自动转换:隐式转换 byte i = 0;        int a =i;        long b = i;        float c =b;        double d =c;        short j =

【java+selenium3】隐式等待+显式等待 (七)

一.隐式等待 -- implicitlyWait 调用方式:driver.manage().timeouts().implicitlyWait(long time, TimeUnit unit); //隐式等待调用方式,5秒+时间单位(枚举类型) driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 注意: 1.隐式等待只能作用于元素的等待. 2.智能等待,如果元素在指定的时间内找到,则不会继续等待,否则在指定时间内未找到

oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理和自定义异常

游标的概念:    游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁 盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库.这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率.游标有两种类型:显式游标和隐式游标.在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种 形式的查询和DML操作,系统都会使用一个隐式游标.但是如果要

隐式意图&amp;显示意图

1 隐式意图 通过指定一组动作或者数据 开启activity 2 显示意图 通过指定具体包名和类名 开启activity 总结 (1)显示意图更加安全一些 (2)开启自己应用的界面用显示意图(不需要配置意图过滤器) (3)隐式意图一般开启系统应用(电话拨号器 短信的发送器等等)的界面

C# 接口的隐式与显示实现说明

以前在用到接口时,从来没注意到接口分为隐式实现与显示实现.昨天在浏览博客时看到相关内容,现在根据自己的理解记录一下,方便日后碰到的时候温习温习. 通俗的来讲,"显示接口实现"就是使用接口名称作为方法名的前缀;而传统的实现方式称之为:"隐式接口实现".费话不说,例子如下: interface IAnimal { void Dog(); } class Animal:IAnimal { public void Dog() { Console.WriteLine(&quo

C# 接口的隐式与显示实现

以前在用到接口时,从来没注意到接口分为隐式实现与显示实现.昨天在浏览博客时看到相关内容,现在根据自己的理解记录一下,方便日后碰到的时候温习温习.  通俗的来讲,“显示接口实现”就是使用接口名称作为方法名的前缀;而传统的实现方式称之为:“隐式接口实现”.费话不说,例子如下:      interface IAnimal { void Dog(); } class Animal:IAnimal { public void Dog() { Console.WriteLine("dog..."

C# 使用隐式或显示实现接口的区别

通俗的来讲,"显示接口实现"就是使用接口名称作为方法名的前缀;而传统的实现方式称之为:"隐式接口实现".费话不说,例子如下:      interface IAnimal { void Dog(); } class Animal:IAnimal { public void Dog() { Console.WriteLine("dog..."); } } 定义了一个IAnimal接口,一般我们都会这么调用: //通过类调用 Animal anima

C#之隐式与显示类型转换

今天在看一篇有关数据类型的文章的时候,无意间看到了两个关键词,"隐式转换"与"显示转换",然后突然想起了当初开始学编程的时候,也总是在代码编译的时候遇到这样的问题. 那么,今天刚好有空来总结一下这两者之间到底存在着怎么样的关系. 先来看看如下几个问题: 我先定义了一个变量: string a = 5; 这个只要是有点常识的人都可以一眼看出问题所在. 然后在看看如下代码: double d1 = 5; float f1 = d1; 按我们所预料的那样,现在我们试着尝试

小议C#接口的隐式与显示实现(续)

上文连接,讲的比较模糊,而且调用起来感觉比较混乱 http://www.cnblogs.com/walleyekneel/p/3581489.html 这次改为显式接口调用,可能项目也有这个一个需求 比如 public interface IA { void Test(); } public interface IB { void Test(); } public class A : IA, IB { public void Test() { //TODO: } } 这里面 Test实现的是IA