Class c1=Date.class;
Class c2=new Date().getClass();
Class c3=Class.forName("java.util.Date");
System.out.println(c1==c2);
System.out.println(c1==c3);
public boolean isPrimitive()判定指定的 Class 对象是否表示一个基本类型。 有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double。 这些对象仅能通过下列声明为 public static final 的变量访问,也是使此方法返回 true 的仅有的几个 Class 对象。
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class c1=Date.class;
Class c2=int.class;
Class c3=Integer.class;
Class c4=Integer.TYPE;
System.out.println(c1.isPrimitive());
System.out.println(c2.isPrimitive());
System.out.println(c3.isPrimitive());
System.out.println(c4.isPrimitive());
System.out.println(c2==c3);
System.out.println(c2==c4);
Class c5=int[].class;
System.out.println(c5.isPrimitive());
System.out.println(c5.isArray());
}
}
public class Test {
public static void main(String[] args) throws Exception{
Constructor constructor1=String.class.getConstructor(StringBuffer.class);//要是用类型
String str2=(String)constructor1.newInstance(new StringBuffer("abc"));//要使用之前类型相同的对象
System.out.println(str2);
String str2=(String)Class.forName("java.lang.String").newInstance();//使用默认的构造方法
}
}
2.2 成员变量的反射应用
“人有身高这一属性”与“我有身高这一属性不同”,也与“我的身高是XXX”不同
public class Test {
public static void main(String[] args) throws Exception{
Person me=new Person(180,140);
Field height_field=Person.class.getField("height");
//height_field指的是取得了Person这个类所具有的一个属性,即身高这样一个属性,并不是取得的某个人的实际身高
System.out.println(height_field.get(me));
Field weight_field=Person.class.getDeclaredField("weight");
weight_field.setAccessible(true);
System.out.println(weight_field.get(me));
}
}
class Person{
public int height;
private int weight;
public Person(int height, int weight) {
super();
this.height = height;
this.weight = weight;
}
}
修改某一对象中的成员变量举例:
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception{
ReflectPoint pt1=new ReflectPoint(3,5);
Field[] fields=ReflectPoint.class.getFields();
for (Field field : fields) {
if(field.getType()==String.class){
String oldValue=(String)field.get(pt1);
String newValue=oldValue.replace("b", "a");
field.set(pt1, newValue);
}
}
System.out.println(pt1);
}
}
class ReflectPoint{
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
@Override
public String toString() {
return "ReflectPoint [x=" + x + ", y=" + y + ", str1=" + str1 + ", str2=" + str2 + ", str3=" + str3 + "]";
}
}
2.3 成员方法的反射
基本应用 “人有跳的能力”与“我有跳的能力”不一样
public class Test {
public static void main(String[] args) throws Exception{
Method methodCharAt=String.class.getMethod("charAt", int.class);//后面指的是传入的参数
//同样,这取得的是String类的这样一个方法,是一种属性,而不是某个对象的成员方法
System.out.println(methodCharAt.invoke("abcde", 1));
//someMethod.invoke(null,parameter)指的是调用的静态方法
}
}
应用: 目标:写一个程序,这个程序能够根据用户提供的类名,去调用类方法
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception{
// TestArguments.main(new String[]{"111","222","333"});
String startingClassName=args[0];
Method mainMethod=Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
/* 如果没有类型转换会出现problems
* Type String[] of the last argument to method invoke(Object, Object...)
* doesn"t exactly match the vararg parameter type. Cast to Object[] to confirm the non-varargs invocation,
* or pass individual arguments of type Object for a varargs invocation.
*/
}
}
class TestArguments{
public static void main(String[] args) {
for (String string : args) {
System.out.println(string);
}
}
}
要修改run configuration
2.4 数组与Object的关系及其反射类型 维度与类型同时相同时,得到的class即相同
public class Test {
public static void main(String[] args) throws Exception{
int[] a0=new int[3];
int[] a1=new int[3];
int[] a2=new int[4];
System.out.println(a0.getClass()==a1.getClass());
System.out.println(a1.getClass()==a2.getClass());
System.out.println(a1.getClass().getName());
}
}
2.5 数组的反射应用 举例
public class Test {
public static void main(String[] args) throws Exception{
printObject(new String[]{"a","b","c"});
printObject("xyz");
}
private static void printObject(Object obj) {
Class c=obj.getClass();
if(c.isArray()){
int len=Array.getLength(obj);
for(int i=0;i
import java.util.HashSet;
public class Test {
public static void main(String[] args) throws Exception{
HashSet set=new HashSet<>();
TestArguments t1=new TestArguments(3);
TestArguments t2=new TestArguments(3);
set.add(t1);
set.add(t2);
System.out.println(set.size());
t1.x=456;
set.remove(t1);
System.out.println(set.size());
}
}
class TestArguments{
int x;
public TestArguments(int x) {
super();
this.x = x;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TestArguments other = (TestArguments) obj;
if (x != other.x)
return false;
return true;
}
}
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class Test {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3, 5);
System.out.println(BeanUtils.getProperty(pt1, "x"));
System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
BeanUtils.setProperty(pt1, "x", "9");//以string的形式对javabean进行操作
System.out.println(pt1.getX());
BeanUtils.setProperty(pt1, "birthday.time", 111);
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
PropertyUtils.setProperty(pt1, "x", 9);//以属性本身的类型的形式对javabean进行操作
System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
}
}
其中ReflectPoint为
import java.util.Date;
public class ReflectPoint {
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
this.birthday = new Date();
}
private int x;
private int y;
private Date birthday;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
三、注解1.了解注解
1.1 @Deprecated
public class AnnotationTest {
public static void main(String[] args) {
sayHello();
}
@Deprecated
public static void sayHello(){
System.out.println("hello!SF.GG!");
}
}
1.2 @Override
@Override
public String toString() {
return "AnnotationTest []";
}
2.注解的定义与反射调用
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@MyAnnotation
public class AnnotationTest {
public static void main(String[] args) {
sayHello();
if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation myannotation=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(myannotation);
}
}
@Deprecated
public static void sayHello(){
System.out.println("hello!SF.GG!");
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@interface MyAnnotation{
}
import java.lang.reflect.Constructor;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws Exception {
ArrayList
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws Exception {
ArrayList collection2 = new ArrayList<>();
ArrayList collection3 = new ArrayList<>();
System.out.println(collection2.getClass() == collection3.getClass());
}
}
也因此,如下代码并不是重载,是错误的,因为运行时会去泛型信息
public static void applyVector(Vector v1){
}
public static void applyVector(Vector v1){
}
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) throws Exception {
ArrayList collection2 = new ArrayList<>();
ArrayList collection3 = new ArrayList<>();
System.out.println(collection3);
printCollection(collection3);//编译器不通过,因为之前说过,泛型类型并不存在类型参数的继承关系
}
public static void printCollection(Collection collection){
}
}
这就需要通配符了
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) throws Exception {
ArrayList collection2 = new ArrayList<>();
ArrayList collection3 = new ArrayList<>();
System.out.println(collection3);
printCollection(collection3);//编译器不通过,因为之前说过,泛型类型并不存在类型参数的继承关系
}
public static void printCollection(Collection> collection){
// collection.add(123);
// 会报错,因为使用了通配符,因此不能调用与类型参数相关的方法
// 参数(int)不适用于Collection 类型的add(capture#1-of?)方法,
collection.size();//这就没错,因为size方法与类型参数没有关系
for (Object object : collection) {
System.out.println(object);
}
}
}
使用?通配符可以引用各种参数类型,其主要作用是引用,而不是写入 通配符也有拓展功能
限定上边界 ? extends Number要求传入的必须是Number的子类
限定下边界 ? super Integer要求传入的必须是Integer的父类
3.自定义泛型
3.1 泛型方法
public class Test {
public static void main(String[] args) throws Exception {
//结果就是二者的交集
Number num=add(3,51.0);
Integer inte=add(3,51);
Object o=add(3,"123");
swap(new String[]{"aaa","bbb","ccc"},1,2);
// swap(new int[]{123,456,789},1,2);//泛型变量只能是引用对象,int[]已经是一个基本类型的数组,它并不能完成自动装箱
}
private static T add(T x,T y){
return null;
}
private static void swap(T[] a,int i,int j){
T temp=a[i];
a[i]=a[j];
a[j]=temp;
}
private static void sayHello() throws T{
try{
}catch(Exception e){//必须明确是哪个异常,不能catch T
throw (T)e;
}
}
}
3.2 在类上定义泛型
就是为了保障类中的泛型能够统一,为此可以在类上定义泛型
public class Test {
public static void main(String[] args) throws Exception {
GenericDao dao=new GenericDao<>();
dao.add("123");
}
}
class GenericDao{
public void add(T x){
}
public T getByID(int id){
return null;
}
public void delete(T obj){
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
public class MyClassLoader {
public static void main(String[] args) throws Exception {
String srcPath = "bin/zheteng/ClassLoaderAttachment.class";
String destPath = "ClassLoaderAttachment.class";
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
System.out.println(new ClassLoaderAttachment().toString());
}
private static void cypher(InputStream ips, OutputStream ops) throws Exception {
int b = -1;
while ((b = ips.read()) != -1) {
ops.write(b ^ 0xff);
}
}
}
class ClassLoaderAttachment extends Date {
/**
*
*/
private static final long serialVersionUID = -1118939564631068343L;
public String toString(){
return "hello,world";
}
}
下面再搞一个解密的类加载器
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
public class MyClassLoader extends ClassLoader {
public static void main(String[] args) throws Exception {
String srcPath = "bin/zheteng/ClassLoaderAttachment.class";
String destPath = "ClassLoaderAttachment.class";
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis, fos);
fis.close();
fos.close();
System.out.println(new ClassLoaderAttachment());
Class d1 = new MyClassLoader().loadClass("ClassLoaderAttachment.class");
Date d = (Date) d1.newInstance();
System.out.println(d.toString());
}
private static void cypher(InputStream ips, OutputStream ops) throws Exception {
int b = -1;
while ((b = ips.read()) != -1) {
ops.write(b ^ 0xff);
}
}
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
String classFileNmae = name;
try {
System.out.println(name);
FileInputStream fis = new FileInputStream(classFileNmae);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cypher(fis, bos);
fis.close();
byte[] bytes = bos.toByteArray();
return defineClass(bytes, 0, bytes.length);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.findClass(name);
}
public MyClassLoader() {
}
}
这次的attachment必须定义为public类否则上面的反射会异常访问权限报错
import java.util.Date;
public class ClassLoaderAttachment extends Date {
/**
*
*/
private static final long serialVersionUID = -1118939564631068343L;
public String toString(){
return "hello,worldxx";
}
}