本人初学Java,孤身奋战,经常被自己搞的头破血流,现有一问题,想与各位高人讨论讨论
我百度了很多关于Class类的文章,看了很多,感觉好像明白了一点,但是又不敢确定,我把我的认识写下来,请各位评价评价。
Class类是一个很特殊的类,在Java源文件编译完成生成的每个class文件中,都有一个Class对象,或者说跟Class这个类有关的一点东西,当JVM加载这个类(记做A)的时候,这个类(A)本身并不参与到JVM中,而是那个跟Class类有关的东西生成了一个Class的对象,这个对象包括了A的所有信息,而也可以说,这个Class对象就是一个包装了类A,让类A来了个改头换面后的一个类A的副本对象。
我的理解就是这样,不知道事实是不是这样,大家认为我理解不对请指出来吧!本来是打算问老师的,可是上次问了他一个超级简单的swing的问题,他支支吾吾硬是没回答我(我目前所出的学校是个专科院校),我觉着还是算了,另外,大家有时间的话,请告诉我一些学Java的途径,我现在老是自己一个人自学,感觉没什么进步,经常性的 :cry: :cry: :cry: ……
Class类就是你new出来的那个对象的模版 你这么想就ok了 Class会记录你new的那个对象的元数据,包括 方法信息 属性信息 实现的接口信息等等等等 虚拟机装载的就是这个Class对象 而你new的东西就是实际对象属性值的集合 看看inside jvm这书很有帮助
难得lz能这么好学 这样的人不多了 加油吧
[color=blue][b]
我是这样理解的:
每一个类被JVM加载后,在内存中生成一个对应的class对象,该class对象是 编译后的class文件,在JVM中的存在方式。[/b][/color]
我这样理解的:
首先,每一个JAVA类会编译成一个class文件,当一个JAVA类被加载到JVM中也,也就是加载对应的class文件了.
然后,Class类的对象是用于包装加载到JVM中的class文件的.它里面的一些成员变量,会记录此class文件,也就是此JAVA类的相关信息.
再次,Class无构造方法,我们无法自已生成一个Class对象,Class对象的生成都是JVM来生成的.
最后:
给你Class的原代码.
[code="java"]/*
package java.lang;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Member;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.InvocationTargetException;
import java.lang.ref.SoftReference;
import java.io.InputStream;
import java.io.ObjectStreamClass;
import java.io.ObjectStreamField;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import sun.misc.Unsafe;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
import sun.reflect.SignatureIterator;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.repository.ClassRepository;
import sun.reflect.generics.repository.MethodRepository;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
import sun.reflect.annotation.*;
/**
Class
represent classes andClass
objectboolean
,byte
, char
, short
,int
, long
, float
, anddouble
), and the keyword void
are alsoClass
objects. *Class
has no public constructor. Instead Class
defineClass
method in the classThe following example uses a Class
object to print the
It is also possible to get the Class
object for a named
@since JDK1.0
*/
public final
class Class implements java.io.Serializable,
java.lang.reflect.GenericDeclaration,
java.lang.reflect.Type,
java.lang.reflect.AnnotatedElement {
private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
registerNatives();
}
/*
/**
getName
. If this Class
object represents aClass
object represents void this method returns/**
Class
object associated with the class orcurrentLoader
denotes the defining class loader ofFor example, the following code fragment returns the
Class
descriptor for the class namedjava.lang.Thread
: *Class
object for the class with the/**
Class
object associated with the class orgetName
) this method attempts toloader
is null, the class is loaded through the bootstrapinitialize
parameter is true
and if it hasIf name
denotes a primitive type or void, an attempt
name
. Therefore, this method cannot be used toClass
objects representing primitiveIf name
denotes an array class, the component type of
For example, in an instance method the expression: *
If the loader
is null
, and a security
checkPermission
methodRuntimePermission("getClassLoader")
permission to/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
/**
new
Note that this method propagates any exception thrown by the
Class
represents an abstract class,private T newInstance0()
throws InstantiationException, IllegalAccessException
{
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public Object run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw new InstantiationException(getName());
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class caller = Reflection.getCallerClass(3);
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
private volatile transient Constructor cachedConstructor;
private volatile transient Class newInstanceCallerCache;
/**
Object
is assignment-compatibleClass
. This method isinstanceof
true
if the specifiedObject
argument is non-null and can be cast to theClass
object withoutClassCastException.
It returns false
Specifically, if this Class
object represents a
true
if the specifiedObject
argument is an instance of the represented class (orfalse
otherwise. IfClass
object represents an array class, this methodtrue
if the specified Object
argumentfalse
otherwise. If this Class
objecttrue
if theObject
argumentfalse
otherwise. IfClass
object represents a primitive type, this methodfalse
. *obj
is an instance of this class */**
Class
object is either the same as, or is a superclass orClass
parameter. It returns true
if so;false
. If this Class
true
if the specified Class
parameter isClass
object; otherwise it returnsfalse
. *Specifically, this method tests whether the type represented by the
Class
parameter can be converted to the typeClass
object via an identity conversionClass
object to be checkedboolean
value indicating whether objects of thecls
can be assigned to objects of this class/**
Class
object represents antrue
if this object represents an interface;false
otherwise. */ public native boolean isInterface();/**
Class
object represents an array class. *true
if this object represents an array class;false
otherwise./**
Class
object represents aThere are nine predefined Class
objects to represent
boolean
, byte
,char
, short
, int
,long
, float
, and double
. *These objects may only be accessed via the following public static
Class
objects for whichtrue
. */**
/**
/**
If this class object represents a reference type that is not an
If this class object represents a primitive type or void, then the
If this class object represents a class of arrays, then the internal
*
Element Type Encoding boolean Z byte B char C class or interface Lclassname; double D float F int I long J short S
The class or interface name classname is the binary name of
Examples:
// cache the name to reduce the number of calls into the VM
private transient String name;
private native String getName0();
/**
If a security manager is present, and the caller's class loader is
checkPermission
RuntimePermission("getClassLoader")
If this object
checkPermission
method denies// Package-private to allow ClassLoader access
native ClassLoader getClassLoader0();
/**
/**
Class
representing the superclass of the entityClass
. If this Class
represents either theObject
class, an interface, a primitive type, or void, thenClass
object representing the Object
class is/**
If the superclass is a parameterized type, the Type
/**
Packages have attributes for versions and specifications only if the
/**
If this object represents a class, the return value is an array
implements
clauses
is an instance ofShimmer
; the value of the expression:Class
object that represents interfaceFloorWax
; and the value of:Class
object that represents interfaceDessertTopping
. *If this object represents an interface, the array contains objects
extends
clause of the declaration of theIf this object represents a class or interface that implements no
If this object represents a primitive type or void, the method
/**
If a superinterface is a parameterized type, the
If this object represents a class, the return value is an
If this object represents an interface, the array contains
If this object represents a class or interface that
If this object represents a primitive type or void, the
/**
Class
representing the component type of anClass
representing the component type of this/**
public
, protected
,private
, final
, static
,abstract
and interface
; they should be decodedModifier
. *If the underlying class is an array class, then its
public
, private
and protected
Class
represents a primitive type or void, itspublic
modifier is always true
, and itsprotected
and private
modifiers are alwaysfalse
. If this object represents an array class, afinal
modifier is alwaystrue
and its interface modifier is alwaysfalse
. The values of its other modifiers are not determinedThe modifier encodings are defined in The Java Virtual Machine
int
representing the modifiers for this class/**
/**
/**
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isMethod())
return null;
MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Class returnType = toClass(typeInfo.getReturnType());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
* type. Matching return type is also necessary
* because of covariant returns, etc.
*/
for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches) { // finally, check return type
if (m.getReturnType().equals(returnType) )
return m;
}
}
}
}
throw new InternalError("Enclosing method not found");
}
}
private native Object[] getEnclosingMethod0();
private EnclosingMethodInfo getEnclosingMethodInfo() {
if (isPrimitive())
return null;
Object[] enclosingInfo = getEnclosingMethod0();
if (enclosingInfo == null)
return null;
else {
return new EnclosingMethodInfo(enclosingInfo);
}
}
private final static class EnclosingMethodInfo {
private Class<?> enclosingClass;
private String name;
private String descriptor;
private EnclosingMethodInfo(Object[] enclosingInfo) {
if (enclosingInfo.length != 3)
throw new InternalError("Malformed enclosing method information");
try {
// The array is expected to have three elements:
// the immediately enclosing class
enclosingClass = (Class<?>) enclosingInfo[0];
assert(enclosingClass != null);
// the immediately enclosing method or constructor's
// name (can be null).
name = (String) enclosingInfo[1];
// the immediately enclosing method or constructor's
// descriptor (null iff name is).
descriptor = (String) enclosingInfo[2];
assert((name != null && descriptor != null) || name == descriptor);
} catch (ClassCastException cce) {
throw new InternalError("Invalid type in enclosing method information");
}
}
boolean isPartial() {
return enclosingClass == null || name == null || descriptor == null;
}
boolean isConstructor() { return !isPartial() && "".equals(name); }
boolean isMethod() { return !isPartial() && !isConstructor() && !"".equals(name); }
Class<?> getEnclosingClass() { return enclosingClass; }
String getName() { return name; }
String getDescriptor() { return descriptor; }
}
private static Class toClass(Type o) {
if (o instanceof GenericArrayType)
return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
0)
.getClass();
return (Class)o;
}
/**
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isConstructor())
return null;
ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
for(Constructor c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches)
return c;
}
}
throw new InternalError("Enclosing constructor not found");
}
}
/**
Class
objectClass
objectClass
object represents an array class, a primitive/**
// JVM Spec 4.8.6: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
return getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
else
return enclosingClass;
}
}
/**
The simple name of an array is the simple name of the
String simpleName = getSimpleBinaryName();
if (simpleName == null) { // top level class
simpleName = getName();
return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
}
// According to JLS3 "Binary Compatibility" (13.1) the binary
// name of non-package classes (not top level) is the binary
// name of the immediately enclosing class followed by a '$' followed by:
// (for nested and inner classes): the simple name.
// (for local classes): 1 or more digits followed by the simple name.
// (for anonymous classes): 1 or more digits.
// Since getSimpleBinaryName() will strip the binary name of
// the immediatly enclosing class, we are now looking at a
// string that matches the regular expression "\$[0-9]*"
// followed by a simple name (considering the simple of an
// anonymous class to be the empty string).
// Remove leading "\$[0-9]*" from the name
int length = simpleName.length();
if (length < 1 || simpleName.charAt(0) != '$')
throw new InternalError("Malformed class name");
int index = 1;
while (index < length && isAsciiDigit(simpleName.charAt(index)))
index++;
// Eventually, this is the empty string iff this is an anonymous class
return simpleName.substring(index);
}
/**
/**
/**
/**
/**
/**
/**
/**
Class
objects representing allClass
object. This includes publicClass
object has no public memberClass
object represents a primitive type, an arrayClass
objects representing the public// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
// is allowed to look at DECLARED classes because (1) it does not hand
// out anything other than public members and (2) public member access
// has already been ok'd by the SecurityManager.
Class[] result = (Class[]) java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public Object run() {
java.util.List list = new java.util.ArrayList();
Class currentClass = Class.this;
while (currentClass != null) {
Class[] members = currentClass.getDeclaredClasses();
for (int i = 0; i < members.length; i++) {
if (Modifier.isPublic(members[i].getModifiers())) {
list.add(members[i]);
}
}
currentClass = currentClass.getSuperclass();
}
Class[] empty = {};
return list.toArray(empty);
}
});
return result;
}
/**
Field
objects reflecting allClass
object. The elements in the array returned areSpecifically, if this Class
object represents a class,
Class
object represents anThe implicit length field for array class is not reflected by this
Array
toSee The Java Language Specification, sections 8.2 and 8.3. *
Field
objects representing the/**
Method
objects reflecting allClass
object, including those declared by the classObject
class. The elements in the arrayClass
objectClass
object represents a primitive type or void. *The class initialization method <clinit>
is not
See The Java Language Specification, sections 8.2 and 8.4. *
Method
objects representing the/**
Constructor
objects reflectingClass
object. An array of length 0 is returned if theMethod
objects for all theparameterTypes
/**
Field
object that reflects the specified publicClass
object. The name
parameter is aString
specifying the simple name of the desired field. *The field to be reflected is determined by the algorithm that
NoSuchFieldException
See The Java Language Specification, sections 8.2 and 8.3.
Field
object of this class specified byname
name
is null
/**
Method
object that reflects the specified publicClass
object. The name
parameter is aString
specifying the simple name the desired method. TheparameterTypes
parameter is an array of Class
parameterTypes
is null
, it isIf the name
is "<init>"or "<clinit>" a
NoSuchMethodException
is raised. Otherwise, the method toSee The Java Language Specification, sections 8.2 and 8.4. *
Method
object that matches the specifiedname
and parameterTypes
[color=blue][b]
给你推荐2本书:
《Java深度历险》(看看第1、2、5三章)
《 java reflection in action 》(有一定基础再看)[/b][/color]
[quote]另外,大家有时间的话,请告诉我一些学Java的途径,我现在老是自己一个人自学,感觉没什么进步[/quote]
[size=large][color=red]我觉得,你可以下载尚学堂的马老师的Java基础视平,看一下看,边看,边动手练习.
我给我一点我的个人建议:
第一,不语言要记一定的东西,基础的语法;关键字;语言固定的代码格式;
比如,你要记class类杂个定义,方法杂个定义,怎么创建新对象;
第二,在基本语言理解的情况下,要多写小程序;来加强对语言的熟悉与亲切感;以前我在看到抛出一大堆异常后,心里就很不爽,现在喜欢上异常了,因为她会帮助我找到错误的代码行;
第三,其实也还是第二点;做项目.小一点的,可以使用java有main的方法的小程序;J2EE方向的,可以使用jsp,jdbc做些信息系统;
总之,要明确理论的重要性与实践的不可或缺!!!![/size]
希望对你有帮助....[/color]
逛逛...
我觉得Class不是像Double这样包装double的类,从感性认识可知它包含某个类的信息(如:字段、属性、方法、构造函数),还可以知道它可以用来实例化该类的对象。
但是,我们每次调用它的newInstance方法后都能得到一个全新的对象。
虽然我们可以这样认为:它面里是直接用对应的对象的类来new出来的。但是,事实上不是这样的。
我的猜想如下:它是通过一个字节数组来定义出来的,这个字节数组就是JVM在加载某个.class文件之后得到的[color=red]一段[/color]字节。事实上,我们也可以通过ClassLoader来手动创建Class对象,每一个Class对象里面都有一个ClassLoader,奥秘就在这个ClassLoader里面,它读取.class文件后调用jdk一系列的本地方法来构造一个Class,这个Class就包含.class的全部数据以供他用。