I have 2 classes, say A & B:
Class A extends B {
public void subClassMthd(){
System.out.println("Hello");
}
}
Class B {
public void printHelloWorld {
System.out.println("Hello");
}
}
Now, I am using reflection to invoke the methods on Class A. I would also like to invoke the printHelloWorld method present in Class B.
I tried using
Class clazz = Class.forName("com.test.ClassA");
Object classAInstance= clazz.newInstance();
Method superClassmthd = classAInstance.getClass()
.getSuperclass().getMethod("printHelloWorld", null);
superClassmthd.invoke(classAInstance);
Also tried as
Class clazz = Class.forName("com.test.ClassA");
Object classAInstance= clazz.newInstance();
Class superClazz = Class.forName(classAInstance.getClass().getSuperclass().getName());
Object superclassInstance = superClazz.newInstance();
Method superClassmthd = superclassInstance.getMethod("printHelloWorld", null);
superClassmthd.invoke(superclassInstance );
But none of them work; they throw an InstantiationException.
What am I doing wrong here?
Try this:
Method mthd = classAInstance.getClass().getSuperclass().getDeclaredMethod("XYZ");
mthd.invoke(classAInstance)
The difference is using getDeclaredMethod(), which gets methods of all visibilities (public, protected, package/default and private) instead of getMethod(), which only gets methods with public visibility.
What is the visibility of the methods you want to call (public, private etc).
If you want to see methods which you cannot call directly, you should use getDeclaredMethod().
Also, what the the constructors of your classes like? InstantiationException indicates that you are having trouble getting an instance of class A (or B).
I have the following code and it works:
A.java
import java.lang.reflect.Method;
public class A extends B {
public static void main(String[] args) throws Exception {
A classAInstance = new A();
Method mthd = classAInstance.getClass().getSuperclass().getMethod("XYZ", null);
mthd.invoke(classAInstance);
}
}
B.java
public class B {
public void XYZ() {
System.out.println("done");
}
}
Related
We have class library as
class A {
public void callWorkflow() {
B b = new B();
}
}
class B {
public void callStatic() {
C.someMethod();
}
}
class C {
public static someMethod() {}
}
We are actually trying to change functionality of static method someMethod. Is there a way to solve this problem without changing call hierarchy?
You can't just Override a static method. In my opinion, remove static from the method someMethod(), then create an object of class C inside class B. Then call the method.
Class A{
public void callWorkflow() {
B b = new B();}
}
Class B{
public void callStatic(){
C c = new C();
c.someMethod();}
}
Class C{
public someMethod(){}
}
There is no way to override a static method.
That's why one of these approaches is preferred to calling static methods:
Inject another object (service) that will provide the functionality in a non-static method and call it through the injected object
Make the static method a thin wrapper that just delegates the work to some non-static object that can be configured (like in slf4j's logger)
I have following classes (note that methods are static):
class Base
{
public static void whosYourDaddy()
{
Class callerClass = // what should I write here to get caller class?
System.out.print(callerClass.getName());
}
}
Class A extends Base
{
public static void foo()
{
A.whosYourDaddy();
}
}
Class B extends Base
{
public static void bar()
{
B.whosYourDaddy();
}
}
And when I call:
A.foo();
B.bar();
I'd like to get output:
AB instead of BaseBase. Is it even possible with static methods (in Java 7)?
What you can do, but shouldn't :) is use the Throwable getStackTrace method. Aside from the smell, this is pretty slow, because getting the stack trace isn't that fast. But you will get an array of StackTraceElement, and each one will contain the class of teh class that is calling it (and you can also get the file and line, and if you separate the two with a : you can get a clickable link in eclipse, not that I'd ever do such a thing...).
Something like
String className = new Throwable().getStackTrace()[1].getClassName();
Hope that helps :)
private static class Reflection {
private static final SecurityManager INSTANCE = new SecurityManager();
static Class getCallClass() {
return INSTANCE.getCallClass(2);
}
private Reflection() {
}
private static class SecurityManager extends java.lang.SecurityManager {
public Class getCallClass(int i) {
Class[] classContext = getClassContext();
if (i >= 0 && i + 1 < classContext.length) {
return classContext[i + 1];
}
return null;
}
};
}
Is it even possible with static methods (in Java 7)?
No, Static methods aren't inherited. Only non-static methods are inherited.
In your case change Base (and subclasses) as follows:
class Base
{
public void whosYourDaddy()
{
Class<?> callerClass = getClass();
System.out.print(callerClass.getName());
}
}
Is it possible to call a super static method from child static method?
I mean, in a generic way, so far now I have the following:
public class BaseController extends Controller {
static void init() {
//init stuff
}
}
public class ChildController extends BaseController {
static void init() {
BaseController.loadState();
// more init stuff
}
}
and it works, but I'd like to do it in a generic way, something like calling super.loadState(), which doesn't seem to work...
In Java, static methods cannot be overidden. The reason is neatly explained here
So, it doesn't depend on the object that it is being referenced. But instead, it depends on the type of reference. Hence, static method is said to hide another static method and not override it.
For example (Cat is a subclass of Animal):
public class Animal {
public static void hide() {
System.out.format("The hide method in Animal.%n");
}
public void override() {
System.out.format("The override method in Animal.%n");
}
}
public class Cat extends Animal {
public static void hide() {
System.out.format("The hide method in Cat.%n");
}
public void override() {
System.out.format("The override method in Cat.%n");
}
}
Main class:
public static void main(String[] args) {
Cat myCat = new Cat();
System.out.println("Create a Cat instance ...");
myCat.hide();
Cat.hide();
myCat.override();
Animal myAnimal = myCat;
System.out.println("\nCast the Cat instance to Animal...");
Animal.hide();
myAnimal.override();
Animal myAnimal1 = new Animal();
System.out.println("\nCreate an Animal instance....");
Animal.hide();
myAnimal.override();
}
Now, the output would be as given below
Create a Cat instance ...
The hide method in Cat.
The hide method in Cat.
The override method in Cat.
Cast the Cat instance to Animal...
The hide method in Animal.
The override method in Cat.
Create an Animal instance....
The hide method in Animal.
The override method in Animal.
For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called.
In other words, call to static methods are mapped at the compile time and depends on the declared type of the reference (Parent in this case) and not the instance the reference points at runtime. In the example, the compile-time type of myAnimal is Animal. Thus, the runtime system invokes the hide method defined in Animal.
There is static inheritance in Java. Adapting the example from Nikita:
class A {
static void test() {
System.out.print("A");
}
}
class B extends A {
}
class C extends B {
static void test() {
System.out.print("C");
B.test();
}
public static void main(String[] ignored) {
C.test();
}
}
This now compiles, and invoking C prints "CA", of course. Now we change class B to this:
class B extends A {
static void test() {
System.out.print("B");
}
}
and recompile only B (not C). Now invoking C again, it would print "CB".
There is no super like keyword for static methods, though - a (bad) justification may be that "The name of the super class is written in the declaration of this class, so you had to recompile your class nevertheless for changing it, so you could change the static calls here, too."
The whole inheritance concept isn't applied to static elements in Java. E.g., static method can't override another static method.
So, no, you'll have to call it by name or make them instance methods of some object. (You might want to check out one of factory patterns in particular).
A practical example
class A {
static void test() {
System.out.println("A");
}
}
class B extends A {
static void test() {
System.out.println("B");
}
}
A a = new B();
B b = new B();
a.test();
b.test();
This prints A and then B. I.e., invoked method depends on how variable is declared and nothing else.
You can actually call the static method of a superclass in a generic way, given that you know the method name and its parameters.
public class StaticTest {
public static void main(String[] args) {
NewClass.helloWorld();
}
}
public class NewClass extends BaseClass {
public static void helloWorld() {
try {
NewClass.class.getSuperclass().getMethod("helloWorld", new Class[] {}).invoke( NewClass.class ,new Object[]{} );
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("myVar = " + myVar);
}
}
public class BaseClass extends BaseBaseClass {
protected static String myVar;
public static void helloWorld() {
System.out.println("Hello from Base");
myVar = "Good";
}
}
This should work and in the subclass you have everything set in the base class available.
The output should be:
Hello from Base
myVar = Good
The official name of your implementation is called method hiding. I would suggest introducing a static init(Controller controller) method, and calling an instance method to take advantage of overriding.
public class Controller {
static void init(Controller controller) {
controller.init();
}
void init() {
//init stuff
}
}
public class BaseController extends Controller {
#override
void init() {
super.init();
//base controller init stuff
}
}
public class ChildController extends BaseController {
#override
void init() {
super.init();
//child controller init stuff
}
}
You can then call Controller.init(controllerInstance).
For static methods there is no instance of a class needed, so there is no super.
I am a Java developer. In an interview I was asked a question about private constructors:
Can you access a private constructor of a class and instantiate it?
I answered 'No' but was wrong.
Can you explain why I was wrong and give an example of instantiating an object with a private constructor?
One way to bypass the restriction is to use reflections:
import java.lang.reflect.Constructor;
public class Example {
public static void main(final String[] args) throws Exception {
Constructor<Foo> constructor = Foo.class.getDeclaredConstructor();
constructor.setAccessible(true);
Foo foo = constructor.newInstance();
System.out.println(foo);
}
}
class Foo {
private Foo() {
// private!
}
#Override
public String toString() {
return "I'm a Foo and I'm alright!";
}
}
You can access it within the class itself (e.g. in a public static factory method)
If it's a nested class, you can access it from the enclosing class
Subject to appropriate permissions, you can access it with reflection
It's not really clear if any of these apply though - can you give more information?
This can be achieved using reflection.
Consider for a class Test, with a private constructor:
Constructor<?> constructor = Test.class.getDeclaredConstructor(Context.class, String[].class);
Assert.assertTrue(Modifier.isPrivate(constructor.getModifiers()));
constructor.setAccessible(true);
Object instance = constructor.newInstance(context, (Object)new String[0]);
The very first question that is asked regarding Private Constructors in Interviews is,
Can we have Private constructor in a Class?
And sometimes the answer given by the candidate is, No we cannot have private constructors.
So I would like to say, Yes you can have private Constructors in a class.
It is no special thing, try to think it this way,
Private: anything private can be accessed from within the class only.
Constructor: a method which has same name as that of class and it is implicitly called when object of the class is created.
or you can say, to create an object you need to call its constructor, if constructor is not called then object cannot be instantiated.
It means, if we have a private constructor in a class then its objects can be instantiated within the class only. So in simpler words you can say, if the constructor is private then you will not be able to create its objects outside the class.
What's the benefit
This concept can be implemented to achieve singleton object (it means only one object of the class can be created).
See the following code,
class MyClass{
private static MyClass obj = new MyClass();
private MyClass(){
}
public static MyClass getObject(){
return obj;
}
}
class Main{
public static void main(String args[]){
MyClass o = MyClass.getObject();
//The above statement will return you the one and only object of MyClass
//MyClass o = new MyClass();
//Above statement (if compiled) will throw an error that you cannot access the constructor.
}
}
Now the tricky part, why you were wrong, as already explained in other answers, you can bypass the restriction using Reflection.
I like the answers above, but there are two more nifty ways of creating a new instance of a class which has private constructor. It all depends on what you want to achieve and under what circumstances.
1: Using Java instrumentation and ASM
Well in this case you have to start the JVM with a transformer. To do this you have to implement a new Java agent and then make this transformer change the constructor for you.
First create the class transformer. This class has a method called transform. Override this method and inside this method you can use the ASM class reader and other classes to manipulate the visibility of your constructor. After the transformer is done, your client code will have access to the constructor.
You can read more about this here: Changing a private Java constructor with ASM
2: Rewrite the constructor code
Well, this is not really accessing the constructor, but still you can create an instance. Let's assume that you use a third-party library (let's say Guava) and you have access to the code but you don't want to change that code in the jar which is loaded by the JVM for some reason (I know, this is not very lifelike but let's suppose the code is in a shared container like Jetty and you can't change the shared code, but you have separate class loading context) then you can make a copy of the 3rd party code with the private constructor, change the private constructor to protected or public in your code and then put your class at the beginning of the classpath. From that point your client can use the modified constructor and create instances.
This latter change is called a link seam, which is a kind of seam where the enabling point is the classpath.
Using java Reflection as follows :
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Test
{
private Test() //private constructor
{
}
}
public class Sample{
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException
{
Class c=Class.forName("Test"); //specify class name in quotes
//----Accessing private constructor
Constructor con=c.getDeclaredConstructor();
con.setAccessible(true);
Object obj=con.newInstance();
}
}
Yes you could, as mentioned by #Jon Steet.
Another way of accessing a private constructor is by creating a public static method within this class and have its return type as its object.
public class ClassToAccess
{
public static void main(String[] args)
{
{
ClassWithPrivateConstructor obj = ClassWithPrivateConstructor.getObj();
obj.printsomething();
}
}
}
class ClassWithPrivateConstructor
{
private ClassWithPrivateConstructor()
{
}
public void printsomething()
{
System.out.println("HelloWorld");
}
public static ClassWithPrivateConstructor getObj()
{
return new ClassWithPrivateConstructor();
}
}
You can of course access the private constructor from other methods or constructors in the same class and its inner classes. Using reflection, you can also use the private constructor elsewhere, provided that the SecurityManager is not preventing you from doing so.
Yes, we can access the private constructor or instantiate a class with private constructor. The java reflection API and the singleton design pattern has heavily utilized concept to access to private constructor.
Also, spring framework containers can access the private constructor of beans and this framework has used java reflection API.
The following code demonstrate the way of accessing the private constructor.
class Demo{
private Demo(){
System.out.println("private constructor invocation");
}
}
class Main{
public static void main(String[] args){
try{
Class class = Class.forName("Demo");
Constructor<?> con = string.getDeclaredConstructor();
con.setAccessible(true);
con.newInstance(null);
}catch(Exception e){}
}
}
output:
private constructor invocation
I hope you got it.
I hope This Example may help you :
package MyPackage;
import java.lang.reflect.Constructor;
/**
* #author Niravdas
*/
class ClassWithPrivateConstructor {
private ClassWithPrivateConstructor() {
System.out.println("private Constructor Called");
}
}
public class InvokePrivateConstructor
{
public static void main(String[] args) {
try
{
Class ref = Class.forName("MyPackage.ClassWithPrivateConstructor");
Constructor<?> con = ref.getDeclaredConstructor();
con.setAccessible(true);
ClassWithPrivateConstructor obj = (ClassWithPrivateConstructor) con.newInstance(null);
}catch(Exception e){
e.printStackTrace();
}
}
}
Output:
private Constructor Called
Reflection is an API in java which we can use to invoke methods at runtime irrespective of access specifier used with them.
To access a private constructor of a class:
My utility class
public final class Example{
private Example(){
throw new UnsupportedOperationException("It is a utility call");
}
public static int twice(int i)
{
int val = i*2;
return val;
}
}
My Test class which creates an object of the Utility class(Example)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
class Test{
public static void main(String[] args) throws Exception {
int i =2;
final Constructor<?>[] constructors = Example.class.getDeclaredConstructors();
constructors[0].setAccessible(true);
constructors[0].newInstance();
}
}
When calling the constructor it will give the error
java.lang.UnsupportedOperationException: It is a utility call
But remember using reflection api cause overhead issues
Look at Singleton pattern. It uses private constructor.
Yes you can instantiate an instance with a private constructor using Reflection, see the example I pasted below taken from java2s to understand how:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Deny {
private Deny() {
System.out.format("Deny constructor%n");
}
}
public class ConstructorTroubleAccess {
public static void main(String... args) {
try {
Constructor c = Deny.class.getDeclaredConstructor();
// c.setAccessible(true); // solution
c.newInstance();
// production code should handle these exceptions more gracefully
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
The basic premise for having a private constructor is that having a private constructor restricts the access of code other than own class' code from making objects of that class.
Yes we can have private constructors in a class and yes they can be made accessible by making some static methods which in turn create the new object for the class.
Class A{
private A(){
}
private static createObj(){
return new A();
}
Class B{
public static void main(String[]args){
A a=A.createObj();
}}
So to make an object of this class, the other class has to use the static methods.
What is the point of having a static method when we are making the constructor private?
Static methods are there so that in case there is a need to make the instance of that class then there can be some predefined checks that can be applied in the static methods before creation of the instance. For example in a Singleton class, the static method checks if the instance has already been created or not. If the instance is already created then it just simply returns that instance rather than creating a new one.
public static MySingleTon getInstance(){
if(myObj == null){
myObj = new MySingleTon();
}
return myObj;
}
We can not access private constructor outside the class but using Java Reflection API we can access private constructor. Please find below code:
public class Test{
private Test()
System.out.println("Private Constructor called");
}
}
public class PrivateConsTest{
public void accessPrivateCons(Test test){
Field[] fields = test.getClass().getDeclaredFields();
for (Field field : fields) {
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
System.out.println(field.getName()+" : "+field.get(test));
}
}
}
}
If you are using Spring IoC, Spring container also creates and injects object of the class having private constructor.
I tried like this it is working. Give me some suggestion if i am wrong.
import java.lang.reflect.Constructor;
class TestCon {
private TestCon() {
System.out.println("default constructor....");
}
public void testMethod() {
System.out.println("method executed.");
}
}
class TestPrivateConstructor {
public static void main(String[] args) {
try {
Class testConClass = TestCon.class;
System.out.println(testConClass.getSimpleName());
Constructor[] constructors = testConClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
TestCon testObj = (TestCon) constructors[0].newInstance();
//we can call method also..
testObj.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Simple answer is yes we can have private constructors in Java.
There are various scenarios where we can use private constructors. The major ones are
Internal Constructor chaining
Singleton class design pattern
Also have another option create the getInstance() where we can create instance of private constructor inside same class and return that object.
class SampleClass1{
private SampleClass1() {
System.out.println("sample class constructor");
}
public static SampleClass1 getInstance() {
SampleClass1 sc1 = new SampleClass1();
return sc1;
}
}
public class SingletonDemo {
public static void main(String[] args) {
SampleClass1 obj1 = SampleClass1.getInstance();
}
}
We can create instance of private class by creating createInstance() in the same class and simply call the same method by using class name in main():
class SampleClass1{
private SampleClass1() {
System.out.println("sampleclass cons");
}
public static void createInstance() {
SampleClass1 sc = new SampleClass1();
}
}
public class SingletonDemo {
public static void main(String[] args) {
//SampleClass1 sc1 = new SampleClass1();
SampleClass1.createInstance();
}
}
Well, you can also if there are any other public constructors. Just because the parameterless constructor is private doesn't mean you just can't instantiate the class.
you can access it outside of the class its very easy to access
just take an example of singaltan class we all does the same thing make the private constructor and access the instance by static method here is the code associated to your query
ClassWithPrivateConstructor.getObj().printsomething();
it will definately work because i have already tested
package reflection;
import java.io.*;
import java.lang.reflect.*;
class class0
{
public void writeout0()
{
System.out.println("class0");
}
}
class class1
{
public void writeout1()
{
System.out.println("class1");
}
}
class class2
{
public void writeout2()
{
System.out.println("class2");
}
}
class class3
{
public void run()
{
try
{
BufferedReader reader= new BufferedReader(new InputStreamReader
(System.in));
String line=reader.readLine();
Class cls=Class.forName(line);
//define method here
}
catch(Exception ee)
{
System.out.println("here "+ee);
}
}
public void writeout3()
{
System.out.println("class3");
}
}
class class4
{
public void writeout4()
{
System.out.println("class4");
}
}
class class5
{
public void writeout5()
{
System.out.println("class5");
}
}
class class6
{
public void writeout6()
{
System.out.println("class6");
}
}
class class7
{
public void writeout7()
{
System.out.println("class7");
}
}
class class8
{
public void writeout8()
{
System.out.println("class8");
}
}
class class9
{
public void writeout9()
{
System.out.println("class9");
}
}
class testclass {
public static void main(String[] args) {
System.out.println("Write class name : ");
class3 example=new class3();
example.run();
}
}
Question is ;
third class will read the name of the class as String from console. Upon reading the name of the class, it will automatically and dynamically generate that class and call its writeout method.If that class is not read from input, it will not be initialized.
but I can't continue any more ; I need to more something for 3.class, what can I do?
Up to this point you have a Class object. You need to instantiate the class to have an object to call a method on. Once you have the instance you need, you can find the method you want with a call to getMethod(String name, Class... parameterTypes) on the Class object. It's helpful if all of the classes have the same method name for the "writeout()" method, otherwise you have to figure out what the method is named inside of the class. Here is the code you're missing to make the call to "writeout()":
Method m = cls.getMethod("writeout", null);
Object writerInstance = cls.newInstance();
m.invoke(writerInstance, null);
With the class and method naming scheme you have in your example, you could figure out the method name by parsing the class name and extracting the number. It's much easier if all the classes share the method name, though.
You need to load the class dynamically via the classloader. A trivial way to do this is to use:
Class.forName(yourClassName);
to get the class object, and then newInstance() to create a new instance of that class. That particular method will only work for classes with a default constructor. See the Class javadoc for more options re. calling constructors.
For generating Java class files dynamically, there is a library, called Byte Code Engeneering Library (BCEL), which will wrap generated byte code instructions around a class file and load it into the runtime.
You will have to learn something about the Java Virtual Machine, though.
I suggest creating an interface, which contains the "writeOut" method. The generated class needs to implement this interface. When you load the class, you don't need (much) reflection for calling the method. The only reflection you'll need is creating an instance of the generated class.
Continue with something like:
//define method here
Method writeout = null;
for( Method m : cls.getDeclaredMethods() ) {
if( m.getName().startsWith("writeout")) {
writeout = m;
break;
}
}
Object o = cls.newInstance();
writeout.invoke( o );
Basically, once you've found the class, you have to find the method you want to invoke and create an instance of that class to finally invoke that method on that new instance.
To understand more ( and better ) all this concepts you should read the java tutorial on the subject: The Reflection API
BTW you are not generating a class here, but rather instantiating it dynamically.
Simple example for your reference:
Class<?> cls_obj = Class.forName("MyClass.java");
Method method = cls_obj.getMethod("show");
Object obj = cls_obj.newInstance();
method.invoke(obj);