Java高级应用(一)
下面来介绍一下Java的高级应用有哪些。
Java高级应用
第一讲 类加载
(一).类加载
类加载器是一个特殊的类,负责在运行时寻找和加载类文件。Java允许使用不同的类加载器,甚至是自定义类加载器。Java程序包含很多类文件,每一个都与单个Java类相对应,这些类文件随时需要随时加载。类加载器从源文件(通常是.class或.jar文件)获得不依赖平台的字节码,然后将它们加载到JVM内存空间,所以它们能被解释和执行。默认状态下,应用程序多的每个类由java.lang.ClassLoader加载。因为它可以被继承,所以可以自由地加强其功能。
1.1 认识Class
Java程序在运行时,运行时系统一直对所有的对象进行运行时类型标识,这项信息记录了每个对象所属的类。JVM通常使用运行时类型信息定位正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
JVM为每种类型管理一个独一无二的Class对像,即每个类(型)都有一个Class对象。运行程序时,JVM首先检查所要加载的类对应的Class对象是否已经加载,如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
Class无公共构造方法,其对象是在加载类时由JVM以及通过调用类加载器中的defineClass方法自动构造的,因此不能显示地声明一个Class对象。每个类都有一个class属性,可以直接以类.class方式访问,也可以通过实例访问,但实例获得class对象必须要调用getClass()方法才可以。
1.2 Class类的方法
static Class forName(String name)————返回指定类名的Class对象(注意静态的)
Object newInstance()————调用缺省构造方法,返回该Class对象的一个实例
getName()————返回此Class对象所表示的实体(类、接口、数组、基本类型或void)名称
Class []getInstance————获取当前Class对象的接口
ClassLoader getClassLoader()————返回该类的加载器
Class getSuperclass()————返回表示此Class所表示的实体的超类的Class
1.3 实践
下面通过继承关系演示Class类的使用,首先定义Person类及其子类Student类。
package com.itsuper.p1.classdemo;
public class Person {
String name;
//如果使用Class的newInstance()构造对象,则需要提供缺省的构造方法
public Person() { }
public Person(String name) {
this.name = name;
}
}
package com.itsuper.p1.classdemo;
public class Student extends Person {
int age;
public Student() { }
public Student(String name, int age) {
super(name);
this.age = age;
}
}
编写测试代码,使用Class类实现Student对象的创建
package com.itsuper.p1.classdemo; public class ClassDemo { /**
* 演示Class类
* @param args
*/
public static void main(String[] args) {
String className = "com.itsuper.p1.classdemo.Student";
//因为调用forName()方法可能抛出异常,需要放到try中
try {
//调用静态方法forName()获取字符串对应的Class对象
Class c1 = Class.forName(className);
//构造一个对象,但是相应的构造类中必须提供缺省的构造函数,才能使用Class类的缺省构造方法
Object obj = c1.newInstance();
//通过类.class,获取Class实例
System.out.println(Student.class);
//通过具体对象,获取Class实例,但具体对象获取Class实例必须调用getClass()方法
System.out.println(obj.getClass().getName());
//判断类.class 与 具体对象获取Class实例是否是统一引用地址
if(obj.getClass()==Student.class){
System.out.println("The Class is Student class!");
}
System.out.println("----------------"); //获取当前Class对象的父类Class对象
Class superClass = c1.getSuperclass();
Object obj2 = superClass.newInstance();
System.out.println(obj2.getClass().getName()); //继续获取父类的Class对象
Class furtherClass = superClass.getSuperclass();
Object obj3 = furtherClass.newInstance();
System.out.println(obj3.getClass().getName()); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
class com.itsuper.p1.classdemo.Student
com.itsuper.p1.classdemo.Student
The Class is Student class!
----------------
com.itsuper.p1.classdemo.Person
java.lang.Object
注意: 调用Class.froName(name)方法时,由于指定的类名可能不存在,需要将其放到try...catch语句块中
JVM为每种类型管理一个独一无二的Class对象。因此可以使用==操作符来比较类对象。通过运行结果分析,可以确定obj.getClass()和Student.class事实上是JVM管理的同一个Class对象。
第二讲 ClassLoader
(二). 认识ClassLoader
类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstap)和用户自定义装载器(user-defined class loader).
自底向上检查类是否已装载 |
Bootstap Classloader | 自顶向下尝试加载类 |
Extension Classloader | ||
System Classloader |
Bootstap(启动类加载器)是JVM自带的类装载器,负责装载Java平台核心类库,如java.lang.*等,在Java中看不到他,是null
Extension(扩展类加载器) 主要负责jdk_home/lib/ext目录下的jar包或—Djava.ext.dirs指定目录下的jar包装入工作
System(系统类加载器) 主要负责java-classpath/-Djava.class.path所指定的目录下的类与jar包装入工作
java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。ClassLoader是一个特殊的用户自定义类装载器,有JVM的实现者提供,如不特殊指定,其将作为系统缺省的装载器。
实践:
代码演示类加载机制的层次关系
public class ClassLoaderDemo {
public static void main(String[] args){
ClassLoader classloader;
classloader = ClassLoader.getSystemClassLoader();
System.out.println(classloader);//sun.misc.Launcher$AppClassLoader@1016632 while(classloader!=null){
classloader = classloader.getParent();
System.out.println(classloader);//sun.misc.Launcher$ExtClassLoader@dc6a77
// null
}//此过程在自底向上判断类加载器 try{
Class c1 = Class.forName("java.lang.Object");//返回Object的对象
classloader = c1.getClassLoader();//获得该对象的类加载器
System.out.println("java.lang.Object`s loader is " + classloader);
c1 = Class.forName("com.itsuper.p1.classdemo.ClassLoaderDemo");
classloader = c1.getClassLoader();
System.out.println("ClassLoaderDemo`s loader is " + classloader);
}catch (Exception e) {
System.out.println("Check name of the class");
}
}
}
运行结果:
sun.misc.Launcher$AppClassLoader@1016632 //表示系统类加载器实例化自sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader@dc6a77 //表示系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
null //表示系统类加载器的parent的parent为bootstap,无法直接获取
java.lang.Object`s loader is null //表示类Object是由bootstap装载的
ClassLoaderDemo`s loader is sun.misc.Launcher$AppClassLoader@1016632 //表示用户自己写的类是由系统类装载器装载的
2.1 加载过程
ClassLoader加载类时,首先检查缓存中是否有该类
(1) 若有直接返回
(2) 若无,请求父类加载
(3) 如果父类无法加载,则从bootstap classLoader加载
然后加载指定类,搜索的顺序是:
(1) 寻找class文件(从与此classloader相关的类路径中寻找)
(2) 从文件载入class
(3) 找不到则抛出ClassNotFoundException
第三讲 instanceof
(三). 认识instanceof运算符
Java的多态性机制导致了引用变量的声明类型和其实际引用的类型可能不一致,在结合动态方法调度机制可以得出结论:声明为同种类型的两个引用变量调用同一个方法时也可能会有不同的行为。为更准确的鉴别一个对象的真正类型,Java语言引入了instanceof操作符。
3.1 定义
instanceof关键字是用于判断一个引用类型变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例。
3.2 使用格式
<引用类型变量> instanceof <引用类型>
注意:该表达式为Boolean类型的表达式,当instanceof左侧的引用类型变量所引入对象的实际类型是其右侧给出的类型或是其子类类型时,整个表达式的结果为true,否则为false。例如mi instanceof MyClass。
3.3 补充
- 子类对象 instanceof 父类,返回true
- 父类对象 instanceof 子类,返回false
- 如果两个类不在同一继承家族中,是用instanceof时会出现错误
- 数组类型也可以使用instanceof来比较
3.4 实践1
下面通过继承关系来演示instanceof关键字的使用
public class InstanceofDemo { public static void typeof(Object obj) {
if(obj instanceof Student){
System.out.println("Student!");
}
if(obj instanceof Person){
System.out.println("Person!");
}
}
public static void main(String[] args) {
Person pobj1 = new Person("tom");
Student sobj1 = new Student("Daming",5);
typeof(pobj1);
System.out.println("-------------------");
typeof(sobj1);
System.out.println("-------------------");
Person pobj2 = new Person("rose");
Student sobj2 = new Student("xiaoli",10);
typeof(pobj2);
System.out.println("-------------------");
typeof(sobj2);
System.out.println("-------------------");
String[] str = new String[2];
if(str instanceof String[]){
System.out.println("true! ");
}
}
}
运行结果:
Person!
-------------------
Student!
Person!
-------------------
Person!
Student!
Person!
-------------------
true!
通过对比结果,有什么发现呢?再仔细的品味一下 这句话吧! “instanceof左侧的引用类型变量所引入对象的实际类型是其右侧给出的类型或是其子类类型时,整个表达式的结果为true”
实践2
定义一个接口IBase和两个类Derive,Derive1来演示instanceof用法
//定义Interface接口IBase
interface IBase{
public void print();
} //定义Derive类实现IBase接口
class Derive implements IBase{
int b;
public Derive(int b) {
super();
this.b = b;
}
//实现接口的抽象方法
public void print(){
System.out.println("In Derive!");
}
} //定义Derive的子类Derive1
class Derive1 extends Derive{
int c;
public Derive1(int b, int c) {
super(b);
this.c = c;
}
public void print(){
System.out.println("In Derive1!");
}
} public class InstanceDemo2 {
//判断对象类型
public static void typeof(Object obj){
if(obj instanceof Derive){
Derive der = (Derive)obj;
der.print();
}else if(obj instanceof Derive1){
Derive1 der1 = (Derive1)obj;
der1.print();
}
} public static void main(String[] args) {
IBase b1 = new Derive(4);//父类引用指向子类对象
IBase b2 = new Derive1(4,5);
System.out.print("b1 is ");
//调用typeof()判断b1对象类型
typeof(b1);
System.out.print("b2 is ");
//调用typeof()判断b2对象类型
typeof(b2);
}
}
运行结果:
b1 is In Derive!
b2 is In Derive1!
Java高级应用(一)的更多相关文章
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- paip.java 架构师之路以及java高级技术
paip.java 架构师之路以及java高级技术 1. Annotation 设计模式... 概念满天飞.ORM,IOC,AOP. Validator lambda4j memcache. 对 ...
- paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型
paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...
- Java高级之线程同步
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于实现多线程的意义,"从业四年看并发"一文已经讲述,而本篇主要讲一下常用的设计 ...
- Java高级之类结构的认识
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! Java体系包括,各种版本的虚拟机,可执行文件,各种第三方类库,Java API类库,Java语言 ...
- Java高级软件工程师面试考纲(转)
如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...
- Java高级软件工程师面试考纲
如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...
- 黑马程序员——Java高级应用(一)
------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...
- 2017最新技术java高级架构、千万高并发、分布式集群、架构师入门到精通视频教程
* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...
- 这月薪过万的Java高级学习资料,难得一遇的干货,不下载真可惜了!
大家有没有想我呢 不管你们想不想我 我挺想你们的 通过昨天我不断的 死气白咧各种说好话 最终 要到了Java学科的Java集合学习资料 里面包含视频+资料+源码 堂兄也有一个愿望 希望你们月薪过万后 ...
随机推荐
- github ssh秘钥配置
1.本地生产ssh密钥对 ssh-keygen -t rsa -C "your_email@example.com" 2. 进入~/.ssh 拷贝公钥进入github里面
- 快速失败(fail—fast)和 安全失败(fail—safe)
快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...
- 插入排序->希尔排序
/** * 插入排序 */ public class InsertSort { public static void main(String[] args){ int[] arr = {5,5,2,6 ...
- centos 6.5 关闭图形界面
图形界面的关闭分为临时关闭和永久关闭,临时关闭重启系统后恢复正常,永久关闭重启系统后图形界面仍然为关闭状态. 临时关闭 init 3 永久关闭 vi /etc/inittab 修改下面一行 id:3: ...
- Spring Security 安全认证
Spring Boot 使用 Mybatis 依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> ...
- RabbitMQ之交换机
1. 交换机类型 rabbitmq常见有四种交换机类型: direct, topic, fanout, headers. 一般headers都不用,工作中用得较多的是fanout,它会将消息推送到所有 ...
- python学习笔记(四)字符串及字符串操作
字符串 字符串可以存任意类型的字符串,比如名字,一句话等等. 字符串还有很多内置方法,对字符串进行操作,常用的方法如下: name1='hello world' print(name.capitali ...
- Java Web学习总结(11)JDBC
一,简介 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的 ...
- Maven开始
1:加入Maven插件: 这句话的意思是: 从本地仓库找到相应的jar包 <localRepository>F:\RepMaven</localRepository 2:创建一个Ma ...
- Windows系统启动iis方法详解
很多网友一般都用Windows 系统自带的iis服务器来配置web网站,在本地进行调试和修改后才正式上线.虽说操作不难,但是小白来说却无从下手,很多人根本不知道iss在哪,怎么启动,更谈不上配置或者其 ...