I'm learning java reflection and I'm curious to know what use java.lang.reflect.Modifier has for a public constructor. The java documentation doesn't give any description or use for it and the class has only static methods and constants.
EDIT: Added some test code.
import java.lang.reflect.*;
public class TestModifier {
Modifier modifier = new Modifier(); // Compiles fine.
// Math math = new Math(); // Won't compile. Math() has private access.
}
The constructor exists and it's present in the javadoc although no info is present.
I found some information about it in the a source code comment in the GNU classpath, a project that is and I quote:
(GNU Classpath, Essential Libraries for Java,) is a GNU project to create free core class libraries for use with virtual machines and compilers for the java programming language.
In their source code for the Modifier class you can find the following non-javadoc comment for the constructor:
This constructor really shouldn't be here ... there are no instance methods or variables of this class, so instantiation is worthless. However, this function is in the 1.1 spec, so it is added for completeness.
I don't know if this is totally accurate since I could only access Java 1.3.1 spec and in the reflection model part of it what you can read is (bold's mine):
The Modifier class is an uninstantiable class that exports class methods to decode Java language modifiers for classes and members. The language modifiers are encoded in an integer, and use the encoding constants defined by The Java Virtual Machine Specification.
I do wanna believe in the comment from the source code, but I can't really point you at the specification where such thing is said.. Even stranger to me is that the previous quote even being from spec 1.3 already states that it's uninstantiable.
This is definitely not an error in javadoc. You can't find such a constructor means this is a default constructor (no arg constructor) which is by default public because the java.lang.reflect.Modifier is a public class.
It might be the property of javadoc if used with default options , that it provides default constructor in documentation if the Parameter-less constructor is not defined for that class and there is no other constructor with parameters.
Good find, this is an oversight of the API designer.
But, it also proves that it is not a big deal at all to instantiate a utility class; new Modifier() has never caused anybody any problem. Neither would new Math().
Don't listen to chicken little.
Related
When I look for the Integer.class file in Eclipse, i can find the getChars Method: https://imgur.com/CPD68sA
But in the official Java Documentation there is no getChars Method: https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
Why?
Because it's not public. It is only used internally.
If you view the access modifier of getChars method, it is default. Hence we cannot use this method on an instance of Integer.
To list down all the method of a class, you can run javap command:
javap java.lang.Integer
The point of javadoc is to document the public API of a class (in the first place).
You only create javadoc for methods that other classes should be using. The method you are asking about is package protected. We are talking about the java.lang package. You can't add classes to that package, so for all practical purpose, you can regard this method to be private.
Coming from there: you simply shouldn't care about such methods. Studying their content might be nice for educational purposes, but they really do not matter for practical purposes. As they represent implementation details. They are subject to change, and you shouldn't rely on them to exist, or even to do a certain thing.
Assume I find something lacking in the default base class Object, and write a class of my own to use instead.
class MyObject extends Object
{
...
}
Is there a way to tell the Java compiler to use my new class as base class instead of the Object class?
Thus avoiding
class MyClass extends MyObject
and just go
class MyClass
and have it implicitly extend MyObject using, say a command line parameter to the compile
javac MyClass --defaultBase=MyObject
That would mean that all Jars and pre-compiled Class-files would use Object, but anything I compile myself would use my own class, except of course, my new base class. (I wouldn't want a circular dependency, would I.)
You can change the Object class within many limitations, but that not really a good idea. The best solution is to create your own class you want other classes to extend.
If you want to extend Object, the best option is to create a Utility method which takes an Object as an argument.
Is there a way to tell the Java compiler to use my new class as base class instead of the Object class?
No. You can't.
The Java Language Specification (JLS 4.3.2) states that the java.lang.Object class is a superclass of all other classes. If a compiler didn't implement that, it wouldn't be a compliant Java compiler. At any rate, I know of no Java compiler ("compliant" or not) that does allow you to do this.
#Peter Lawrey mentions that it is possible to change the Object class. This is true ... if you know what you are doing. But there are dependencies on internal details of the Object class hard-wired into other class ... and the native code implementation of the JVM. If you change some things (for example, adding instance fields or changing method signatures) you are liable to break the JVM, tools in the Java tool-chain, and/or 3rd-party libraries and tools (like your favourite IDE!). The breakage is liable to be castrophic, and difficult to diagnose.
On top of that, if your change doesn't break Java, you are still stuck with the problem that a real JVM won't run your code. That makes monkeying with Object a viable proposition for "research purposes only" ... at best.
For the record, it is technically possible to override the core classes of the the Java runtime library using the -Xbootclasspath VM option(s) (type java -X to get the info). However, this is not intended to be done by a usual developer (see other answers to this question).
You can try it yourself by modifying and compiling the source of the java.lang.Object to a directory named core-classes, for example, and passing the -Xbootclasspath/p:core-classes as a JVM argument.
I kind of new to java and will be happy if anybody could explain the following code samples to me.This is just a sample java code snippet for illustration. But the main question is that if the class Learn initializes another class Smart with a parameter which is also a class Object , then the addition of the dot class to the class Object Sample is kind of confusing to me. Any explanation will be appreciated. I apologize if it is a basic question. thanks.
class Learn {
//some codes
Smart smart = new Smart(Sample.class);
//some codes
}
Sample is the name of a class. It is not an object. A new Sample() is an object whose class is Sample. Sample.class is an object whose class is java.lang.Class which describes the class Sample.
In java, there is a class called "Class" that represent classes and interfaces.
There are several ways to get an instance of class "Class". Please take a look at java.lang.Class document.
Class.forName(String className)
obj.getClass() -obj is any class instance
Sample.class -Sample is a class
You are using the 3rd method to get an instance of class "Sample".
I will break your example in the following way....
Learn - is a Class
smart - is an Object Reference Variable of type Smart, we can say that Class Learn has a reference of type Smart.
Sample.class - Is a way of getting the Class<T> for a particular type.
Extract from Java Docs.
During implementation it depends on the Targeting bytecode version. If -target 1.4 (or below), a call to Class.forName() is inserted into your code in a static method which is called during type initialization. If you use -target 1.5 (or above) the constant pool gets a "class" entry
Please refer section 15.8.2 of the Java Language Specification for more details
Can a class add a method to itself at runtime (like from a static block), so that if someone is performing reflection on this class, they'll see the new method, even though it wasn't defined at compile time?
Background:
A framework I'm using expects Action classes to be defined that have a doAction(...) method, by convention. The framework inspects these classes at runtime to see what type of parameters are available in their doAction() method. For example: doAction(String a, Integer b)
I'd like each class to be able to programatically generate its doAction() method with various parameters, just-in-time when it is inspected. The body of the method can be empty.
It's not simple. Once a class is loaded by a classloader, there is no way to change the methods of loaded classes. When a class is requested, a classloader will load it and link it. And there is no way (with Java) to change the linked code or to add/remove methods.
The only trick that comes to my mind is playing with classloaders. If we delete a custom classloader, then the classes loaded by that classloader should be deleted or inaccessible too. The idea that comes to my mind is to
implement one custom classloader
load the dynamic class with that custom classloader
if we have an updated version of this class,
remove the custom classloader and
load the new version of this class with a new instance of the custom classloader
I leave that as food for thought, can't prove, if this leads to a solution or if we have pitfalls.
As a simple answer to the question: No, we can't change a loaded class like we can change the content of fields with reflection. (we can't add or remove fields too).
Andres_D is right, we can very well do so using custom class loading, here is a detailed guide on how to do this: http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=1
The article explains how to write dynamic Java code. It discusses runtime source code compilation, class reloading, and the use of the Proxy design pattern to make modifications to a dynamic class transparent to its caller.
In fact researcher in Austria have written a JVM that even allows reloading classes with different type hierarchies. They have achieved this by using existing thread save points to generate a complete 'side universe' of an object and all it's related references and referenced content and then once fully reshuffled with all required changes simply swap in all changed classes. [1] Here a link to their project http://ssw.jku.at/dcevm/ the oracle sponsorship certainly makes for interesting speculations on future plans.
Less intrusive changes to method bodies and fields are already possible in the standard java VM using the Hot Swap capabilities of the JPDA as introduced in Java 1.4:
docs.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap
I'm not sure whether it was the first one but this Sun employee's paper from 2001 appears to be one of the early proposals mentioning the capabilities of the HotSpot to Hot Swap. [2]
REFERENCE
[1] T. Würthinger, C. Wimmer, and L. Stadler, “Dynamic Code Evolution for Java,” presented at the 8th International Conference on the Principles and Practice of Programming in Java, Vienna, 2010.
[2] M. Dmitriev, “Towards flexible and safe technology for runtime evolution of java language applications,” in OOPSLA Workshop on Engineering Complex Object-Oriented Systems for Evolution, 2001.
I've never tried anything quite like that myself, but you should have a look at ASM, cglib, and Javassist.
No, that is not (easily) possible in Java.
It sounds like you are trying to use Java as if it is a dynamic programming language. For example, Ruby has open classes: you can add and remove methods from Ruby classes at runtime. In Ruby, you can also have a "method missing" method in your class, that will be called when you try to call a method that doesn't exist in the class. Such a thing also doesn't exist in Java.
There is a version of Ruby that runs on the JVM, JRuby, and it has to do very difficult tricks to make open classes work on the JVM.
You can have a doAction method which does whatever you would like the generated method to do. Is there a reason it needs to be generated or can it be dynamic?
It looks like there is no way to add method dynamically. But you can prepare an class with a list of Methods or an hash like:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
public class GenericClass {
private HashMap<String, Method> methodMap = new HashMap<String, Method>();
public Object call(String methodName,Object ...args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method method = methodMap.get(methodName);
return method.invoke(null, args);
}
public void add(String name,Method method){
if(Modifier.isStatic(method.getModifiers()))
methodMap.put(name, method);
}
public static void main(String[] args) {
try {
GenericClass task = new GenericClass();
task.add("Name",Object.class.getMethod("Name", new Class<?>[0]));
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
Than, using reflections you can set or unset the attribute.
I believe you need some byte code altering tool/framework, such as asm, cglib or javassist.
You can achieve this via aspects/weaving like it's done Spring, but I believe you still need to have the method defined first.
Proxy may help. But have to instantiate a Proxy every time you want to add or remove a method.
What I suggest should work for your situation:
1. You have an existing class MyClass with n methods
2. You want to include (n+1) th method which is not in the class while compiling in another .java source file
My way to solve it is Inheritance. Create a new .java source file for a Class MyClassPlusOne extending the first class MyClass. Compile this class and use the object. How can I compile and deploy a java class at runtime?
class MyClassPlusOne extends MyClass
{
void doAction(String a, Integer b)
{
int myNPlus1 = a+b;
//add whatever you want before compiling this code
}
}
I'm not sure that is possible. However, you could use AspectJ, ASM, etc. and weave these methods into the appropriate classes.
The other alternative is to use composition to wrap the target class and provide the doAction method. You would end up delegating to the target class in this case.
This is a rather old question, but I still found myself looking at it today so, just in case, I'll add my two cents.
If you are using Java 8+, you can define "default" implementations of an interface method, so you can just define the interface with all the extra methods with empty default implementations, and add the implements clause in the desired classes. This approach, in some cases, may be the easiest one.
If you don't have control over the definition of the classes, or you need compatibility with older Java versions, you can still define an interface containing all the required extra methods; but in this case, implement a "Decorator" class with a method that receives the object to "decorate" as parameter, and returns a DynamicProxy instance, wrapping the passed object with this interface.
If you are using Spring, the decorator can be added to the context as a #Component, so you can inject it wherever you need to use it. If any of the objects you need to inject are Spring Beans, you could implement a FactoryBean that uses the decorator to return the instances, so you can just forget about calling the decorator explicitly for them.
There is a statement in the book I'm reading for the SCJP qualification, it says :
Files with no public classes have no
naming restrictions
That has made me ask, why would you ever want to do this?
If there are no public classes, then how could other classes ever import and use the file? The only purpose I can see is if the file runs standalone in itself, which could also be odd, such as have an entire application in one file
This is valid for package-private classes as well. And you can use package-private classes within the same package. (And in that case you don't have to import it, because it's in the same package.)
For example, the JapaneseImperialCalendar class is package-private, because it is only used from Calendar.createCalendar(..) - it is not part of the public API. You can't directly instantiate the japanese calendar, but you can still use it by its interface. Same goes for all unmodifiable collections that are obtained by methods like Collections.unmodifiableList(..) - they are package-private.
So the .java file of JapaneseImperialCalendar could've been arbitrary. However, it is advisable not to diverge from the established practice of naming even package-private files after the class name.
You can create a file named package-info.java, which contains only a package statement. The javadoc 1.5+ tool treats a javadoc comment on this package statement exactly like a package.html file. In addition, you can add package-level annotations such as #Generated to this statement, which you can't do in package.html.
Because package-info is not a valid Java identifier, there is no risk of this file ever clashing with an existing Java class (i.e. backwards compatibility).
From Java Classes, you have public classes and package classes. Package classes are considered "private" so that you can only use them within the package itself. This is the default, i.e. no public is specified.
Public classes are, of course, classes that you can create anywhere.
Even though I am very late in answering the question, but this will surely help a lot. If I am not wrong, your concrete question boils down to this - What is the significance of a class declared with no no explicit modifier?
Have a look at this class present in java.util package-
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E>
Also see within the same package-
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>
You see both of them are declared with no explicit modifier. Have you wondered why the package private restriction? Here's the reason from the amazing book Effective Java 2nd Edition by Joshua Bloch #Item1
The class java.util.EnumSet (Item 32), introduced in release
1.5, has
no public constructors, only static factories. They return one of two implementations, depending on the size of the underlying enum type: if it has sixty-four or fewer elements, as
most enum types do, the static factories return a RegularEnumSet
instance, which is backed by a
single long; if the enum type has sixty-five or more elements, the factories return a JumboEnumSet instance, backed by a long
array.
Move swiftly on, he further adds-
The existence of these two implementation classes is invisible to
clients. If RegularEnumSet ceased to offer performance advantages for
small enum types, it could be eliminated from a future release with no
ill effects. Similarly, a future release could add a third or fourth
implementation of EnumSet if it proved beneficial for performance.
Clients neither know nor care about the class of the object they get
back from the factory; they care only that it is some subclass of
EnumSet.
I don't agree with the non-restriction. Each java file should contain only one top level class, and the file name should be the same as the class name, public or not. I don't think javac would like this very much (or any human being)
A.java
class B
B.java
class A
http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.3
7.2 Host Support for Packages
Each host determines how packages,
compilation units, and subpackages are
created and stored, and which
compilation units are observable
(§7.3) in a particular compilation.
7.2.1 Storing Packages in a File System
As an extremely simple example,
http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html
both source and class files must have
root names that identify the class.
For example, a class called MyClass
would be written in a source file
called MyClass.java and compiled into
a bytecode class file called
MyClass.class.