Class类的作用
Class类是一个特殊类,它用于表示JVM运行时类或接口的信息。
Class类提供很多方法用于获取类的各种信息,比如获取类名、判断该类是否是一个接口还是普通类等等。
在Java中枚举类是一种类,而注解是一个接口,数组也是一个类;Java原始类型(boolean, byte, char, short, int, long, float, and double)和关键字void也被表示为Class的对象。
你知道吗?
在每一个基本类型的包装类中都有一个共有的静态变量,例如Integer:
public static final Class TYPE = (Class) Class.getPrimitiveClass(“int”);
TYPE就是这个基本类型的Class对象表示。
一个类只有被JVM加载后才能使用,需要经过加载-->验证-->准备-->解析-->初始化五个阶段。
当类被虚拟机加载后都会在内存中创建一个该类的Class对象,用于存储该类的各种信息。
Class类的构造函数被设计为私有的,这意味着我们不能通过new的方式来创建Class对象,只有JVM才能创建该类的实例。因为类的加载不是我们负责的,只有JVM才知道如何加载一个类。
Class类的父类
Class类是java中的一个类和其他非继承类一样,默认的父类也是Object。
可以使用下面的方式验证:
public class ClassParentTest {
public static void main(String[] args) {
boolean assignableFrom = Object.class.isAssignableFrom(Class.class);
System.out.println(assignableFrom);
}
}
Class#isAssignableFrom(Class cls)方法用于判断cls的实例能否赋值给该Class的引用;换句话说,该方法可以用来判断cls类是否是该Class的子类或者如果Class是接口表示cls是否实现了该接口。
上边那段代码将输出true,说明Class类的父类是Object类。
Class类的forName方法
用于手动加载一个类,该方法是一个公共静态方法,有多个重载。
方法签名:
public static Class<?> forName(String className)
public static Class<?> forName(String name, boolean initialize,ClassLoader loader)
throws ClassNotFoundException
//下面这个是JDK9新增加的,用于从模块中加载一个类,不对类进行初始化
public static Class<?> forName(Module module, String name)
//第一个和第二个都是调用下面的native方法forName0来加载类
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader,
Class<?> caller)
关于参数boolean initialize
注意这里的参数boolean initialize表示是否对类进行初始化,这里的初始化指的是类加载过程中收集静态代码块和静态变量形成的方法的初始化,不是指类构造函数的执行(构造函数的执行是在类生成实例的时候执行的,是对实例变量的初始化,不要搞混!)。
看下面的例子:
class A{
private static final int i = 0;//#1
private static final String str = "hello";//#2
static {
System.out.println("static block!"); //#3
}
public A(){
System.out.println("constructor!");
}
}
在类加载的过程中,会将#1,#2,#3按照顺序收集在一起形成方法,为了帮助理解,可以表示成下面的伪代码:
<clinit>() {
private static final int i = 0;//#1
private static final String str = "hello";//#2
System.out.println("static block!"); //#3
}
参数boolean initialize就是来表示是否在类加载的时候执行这个方法!
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<A> aClass = (Class<A>) Class.forName("com.company.A",
true,Test4.class.getClassLoader());
}
上边的代码将参数initialize设置为true,执行会输出static block!,说明执行了类的初始化!
如果改成false,将不会输出static block!,也就是不执行类的初始化,这将类的初始化延迟到第一次创建该类的实例!
类的构造函数是类实例化时执行的。
A a = aClass.getConstructor().newInstance();
通过以上方式创建A类的实例将输出constructor!
Class类的isInstance和isAssignableFrom方法
这两个方法都是native方法。
isInstance
方法签名:
public native boolean isInstance(Object obj);
isInstance用于判断obj对象是否是该Class或该Class子类的一个实例。
例如:
String hello = "hello";
boolean isStr = String.class.isInstance(hello);
isStr为true。
boolean is = Number.class.isInstance(Integer.valueOf(1));
is为true,因为Integer是Number的子类。
该方法还可以用于类型转换时,为了避免对象的转换异常,进行类型检查:
public void method(Object str){
String str1;
if(String.class.isInstance(str)){
str1 = (String) str;
}
}
但是我们一般不会这样写,因为java给我提供了instanceof。
isAssignableFrom
方法签名:
public native boolean isAssignableFrom(Class<?> cls);
该方法用于判断cls的实例能否赋值给该Class的引用;换句话说,该方法可以用来判断cls类是否是该Class的子类或者如果Class是接口表示cls是否实现了该接口。
例如:
boolean is = Number.class.isAssignableFrom(Integer.class);
boolean is2 = List.class.isAssignableFrom(ArrayList.class);
is和is2都是true,因为Integer继承了Number,ArrayList间接的实现了List接口。
看Spring中的一段代码(代码摘自MapMethodProcessor类,HandlerMethodArgumentResolver的实现类,用于自动注入Controller方法参数):
@Override
public boolean supportsParameter(MethodParameter parameter) {
return Map.class.isAssignableFrom(parameter.getParameterType()) &&
parameter.getParameterAnnotations().length == 0;
}
它使用isAssignableFrom方法来判断方法参数是否是Map类型。
Class类的isXXXX
Class类还提供了isXXXX的方法,这些方法大多用于判断Class的类型。
方法名方法签名作用
isInterface
public native boolean isInterface()
判断该Class是否是一个接口
isArray
public native boolean isArray()
判断该Class是否是一个数组 (数组在Java中也是类)
isPrimitive
public native boolean isPrimitive()
判断该Class是否是基本类型
isAnnotation
public boolean isAnnotation()
判断该Class是否是一个注解,如果该方法返回true,isInterface方法也将返回true,因为注解是特殊的接口
isSynthetic
public boolean isSynthetic()
当且仅当该Class是Java语言规范定义的合成类时为true。
isAnonymousClass
public boolean isAnonymousClass()
当且仅当该Class是匿名类时返回true。Runnable runnable = new Runnable() { public void run() { }};boolean is = runnable.getClass().isAnonymousClass();为true
isLocalClass
public boolean isLocalClass()
当且仅当该Class是局部类时返回true。
isMemberClass
public boolean isMemberClass()
当且仅当该Class是一个类的成员返回true
isAnnotationPresent
public boolean isAnnotationPresent(Class
HTML中<a></a>标签的四大功能 必看!必看!!必看!!!
文章速览:
HTML基础知识的学习+附加常用HTML标签
HTML中有序列表(<ol><li>)和无序列表(<ul><li>)以及定义列表的使用,以及利用无序列表制作网购按钮
HTML中图片的网页插入以及属性设置
HTML中<a></a>标签的四大功能 必看!必看!!必看!!!
HTML表单标签<form></form>登录窗口和单选框以及下拉栏的制作
a标签的第一个功能:超链接
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<a href="https://www.baidu.com/"> 百度一下 a>
body>
html>
说明:href 属性是用来指向你点击需要访问链接的地址,后面的写的”百度一下“是来告诉用户的
即:
点击之后就会自动跳转href后面所写的地址。
注意:不一定非要点击所写的文字进行访问链接,可以是图片,下面展示
<body>
<a href="https://www.baidu.com/" style="width: 100px; height: 100px; background-color: chartreuse; display: block;"> a>
body>
改成上面的代码之后,就会出现一个块元素,点击块元素就能够跳转网址
‘display一般设置为block 或者inline 或者是none,首先你应该理解元素默认是内联还是块,如:a标签为内联元素,但是有时为了让他变成块元素,就要使用display:block来转变了!
还是应该先了解标签的默认属性,还应该了解内联和块的区别!
当然根据上面的方法,也能够设置一张图片进行访问地址:
<body>
<a href="https://www.baidu.com/" >
<img src="images/dilireba.jpg">
a>
body>
将代码改写成上面的代码,就可以通过图片就行访问地址链接了:
注意:通过上面的三种链接访问的方式,发现每次打开链接都是在同一个网页中打开的,那么怎么能够将打开的链接在新的网页中打开呢,下面进行讲解
其实很简单,只需要再加一个属性即可:
<body>
<a href="https://www.baidu.com/" target="_blank"> 百度一下 a>
body>
可以看出上面又新加了一个属性 target(即为目标的意思),然后在该属性中放一个值 ”-blank“即为空的页,不要忘记blank前面有一个下划线
从上图可以看出,是在新的网页中打开的百度
a标签的第二个功能:
a——anchor:锚的意思(定在某个点上)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div style="width:100px; height:100px; background-color:rgb(20, 220, 120)"> demo1 div>
<div style="width:100px; height:100px; background-color:crimson"> demo2 div>
<a href=""> find demo1 a>
<a href=""> find demo1 a>
body>
html>
此时已经初部形成:
如果想让第一个a标签记录第一个div标签的位置,让第二个a标签记录第二个div的位置
那么首先呢先给两个div分别做个唯一标识 id
然后再在两个a标签中分别写出#demo1与#demo2
这样第一个a标签记录第一个div标签的位置,让第二个a标签记录第二个div的位置就完成了
<body>
<div id="demo1" style="width:100px; height:100px; background-color:rgb(20, 220, 120)"> demo1 div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div id="demo2" style="width:100px; height:100px; background-color:crimson"> demo2 div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<a href="#demo1"> find demo1 a>
<a href="#demo2"> find demo2 a>
body>
上面那么多br换行标签是为了将两个块元素分开,方便看到锚点的作用
可以看出,两个块元素和两个锚点在一个页面被分割开了,所以,此时操作更能看出锚点的作用
点击第一个锚点的时候,自动跳转记录该锚点位置的块元素
在上面的代码可以看出,两个锚点在最底端,寻找起来是很不方便的,那么怎么才能给这两个锚点置顶或者换个位置呢,请继续往下看:
<body>
<div id="demo1" style="width:100px; height:100px; background-color:rgb(20, 220, 120)"> demo1 div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div id="demo2" style="width:100px; height:100px; background-color:crimson"> demo2 div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<a href="#demo1" style="display: block; position: fixed; bottom:150px;right:100px;
border:1px solid black; height: 50px; width:200px; background-color:#fcc"> find demo1 a>
<a href="#demo2" style="display: block; position: fixed; bottom:100px;right:100px;
border:1px solid black; height: 50px; width:200px; background-color:#ffc"> find demo2 a>
body>
其中position是用来确定位置的,bottom 说明锚点固定在底部
a标签的第三个功能:打电话、发邮件:
<body>
<a href="tel:110"> 给清华招生办打电话 a>
body>
当该程序在手机上运行的时候,就会调用通讯录进行打电话(如果是苹果系统的话,也可以用电脑进行打电话呼出)
将上面的代码稍作修改就可以改为发邮箱:
<body>
<a href="mailto:123456789@qq.com"> 给清华招生办发邮件a>
body>
当点击后,会自动弹出发邮件的窗口:
a标签的第四个功能:协议限定符:(小小的黑客功能)
<body>
<a href="javascript:while(1){alert('让你看,看屁')}"> 点击我查询成绩a>
body>
说明:
javascript就是协议限定符,在后面可以加文字显示
写上javascript后,a标签就会强制运行javascript代码
javascript是很有逻辑的很有结构的
可以在后面写一个死循环{while(1)}
其中alert属性是弹出框