从头认识java-12.6 接口与类型信息(怎么绕过接口直接调用类的所有方法)

这一章节我们来讨论一下接口与类型信息。

在之前的章节里面我们提到接口,父类引用子类对象,然后把方法给缩窄了,但是我们这一章节学习到反射,这个约束就变得没有那么严格。

我们来看看下面的例子:

package com.ray.ch11;

public class Test {
	public static void main(String[] args) {
		Person man = new Man();
		man.sleep();
		man.run();
		// man.say();//error
	}
}

interface Person {

	public void sleep();

	public void run();
}

class Man implements Person {
	public void say() {
	}

	@Override
	public void sleep() {
	}

	@Override
	public void run() {
	}
}

我们一般的代码就会向上面一样,直接定义接口,然后接口指向实现的类。一般的情况就像上面一样,方法给变少了。但是,我们修改一下方法:

package com.ray.ch11;

public class Test {
	public static void main(String[] args) {
		Person man = new Man();
		man.sleep();
		man.run();
		// man.say();//error
		if (man instanceof Man) {
			Man man2 = (Man) man;
			man2.say();
		}
	}
}

interface Person {

	public void sleep();

	public void run();
}

class Man implements Person {
	public void say() {
	}

	@Override
	public void sleep() {
	}

	@Override
	public void run() {
	}
}

我们修改了一下,通过isInstanceOf方法,来向下转型,这样我们就可以得到Man里面所有的方法,甚至是下面的代码:

package com.ray.ch11;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
	public static void main(String[] args) {
		try {
			Class<?> manClass = Class.forName("com.ray.ch11.Man");
			Man man = (Man) manClass.newInstance();
			Method[] methods = man.getClass().getDeclaredMethods();
			for (Method method : methods) {
				System.out.println(method.getName());
			}
			Method sayMethod = manClass.newInstance().getClass()
					.getDeclaredMethod("say");
			sayMethod.setAccessible(true);
			sayMethod.invoke(man);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}

interface Person {

	public void sleep();

	public void run();
}

class Man implements Person {
	private void say() {
		System.out.println("method say");
	}

	@Override
	public void sleep() {
	}

	@Override
	public void run() {
	}
}

通过上面的代码,我们直接调用类里面所有的方法,包括私有方法。

这个对于封装来说是比较致命的,因此,我们提供的服务端代码一般都隐藏了类的信息,例如:

package com.ray.ch11;

public class Test {

	public static Person makePerson() {
		return new Man();
	}

	public static void main(String[] args) {
		Person person = makePerson();
	}
}

interface Person {

	public void sleep();

	public void run();
}

class Man implements Person {
	private void say() {
		System.out.println("method say");
	}

	@Override
	public void sleep() {
	}

	@Override
	public void run() {
	}
}

我们通过一个方法隐含了类的实现,全部是以接口的形式对外展现,这样就可以避免了上面的一些问题。

总结:这一章节主要讲述了接口与类型信息的内容,需要注意跨过接口直接调用类的情况。

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

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

目录

时间: 12-09

从头认识java-12.6 接口与类型信息(怎么绕过接口直接调用类的所有方法)的相关文章

Java基础知识强化之集合框架笔记33:Arrays工具类中asList()方法的使用

1. Arrays工具类中asList()方法的使用 1 public static <T> List<T> asList(T... a): 把数组转成集合 注意事项: 虽然可以把数组转成集合,但是集合的长度不能改变. 2. 代码示例: (1) 1 package cn.itcast_03; 2 3 import java.util.Arrays; 4 import java.util.List; 5 6 /* 7 * public static <T> List<

深入理解Java类型信息(Class对象)与反射机制

深入理解Class对象 RRTI的概念以及Class对象作用 认识Class对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RRTI的说法则是源于<Thinking in Java>一书,其作用是在运行时识别一个对象的类型和类的信息,这里分两种:传统的"RRTI",它假定我们在编译期已知道了所有类型(在没有反射机制创建和使用类对象时,一般都是编译期已确定其类

【Java核心技术】类型信息(Class对象 反射 动态代理)

1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有"常规"对象的,Java使用Class对象来执行RTTI,即使你正在执行的是类似类型转换这样的操作. 每个类都会产生一个对应的Class对象,也就是保存在.class文件.所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类.Class对象仅在需要的时候才会

《JAVA编程思想》学习笔记——第十四章 类型信息

运行时类型信息使得你可以在程序运行时发现和使用类型信息. 主要有两种方式:一种是"传统的"RTTI, 它假定我们在编译时已经知道了所有的类型;另一种是"反射"机制,它允许我们在运行时发现和使用类的信息. Class对象 类是程序的一部分,每个类都有一个Class对象.换言之,每当编写并且编译一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名的.class文件中).为了生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为"类

深入理解Java类型信息(Class对象)与反射机制(干货)

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/70768369 出自[zejian的博客] 本篇主要是深入对Java中的Class对象进行分析,这对后续深入理解反射技术非常重要,这篇有点偏向内功类文章,主要内容如下: 深入理解Class对象 RRTI的概念以及Class对象作用 Class对象的加载及其获取方式 Class对象的加载 ClassforName方法 Class字面常

java 27 - 6 反射之 通过配置文件运行类中的方法

在以前,如果我们想要调用一个类中的方法,只能这样子: 例: 有Cat和Dog两个类,里面有eat和run两个成员方法: 1 public class Dog { 2 3 public void eat() { 4 System.out.println("狗吃肉"); 5 } 6 7 public void run() { 8 System.out.println("狗刨"); 9 } 10 } public class Cat { public void eat()

【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析

一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 接口定义的一般形式为: [访问控制符]interface <接口名> { 类型标识符final 符号常量名n = 常数: 返回值类型  方法名([参数列表]); … } 二.接口的特点 1.Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显

[原创]java WEB学习笔记27:深入理解面向接口编程

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

JDBC数据类型、Java数据类型、标准sql类型

本文转自:http://www.cnblogs.com/shishm/archive/2012/01/30/2332142.html 谢谢原作者细心的总结,很赞! 本概述是从<JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference>这本书中摘引来的.JavaSoft 目前正在准备这本书.这本书是一本教程,同时也是 JDBC 的重要参考手册,它将作为 Java 系列的组成部份,在 1997 年春季由 Addis