i am trying to pass method local inner class object as an argument to some other function either in the scope of outside class or out of that class
public class MethodClass {
public void p(){
class h{
public void h1(){
System.out.print("Java Inner class");
}
}
h h2=new h();
}
}
here h2 i want to pass to any other function in the same class MethodClass or out of that class. can any one give me the procedure to pass the argument in that way?
If another method needs to know about the class, then you shouldn't declare it within a method, basically. Make it a nested class within the class itself, or even a top-level class.
I can't say I've ever used method-local class declarations.
Related
I have an Interface (call it Planet) whose implementation class is protected, and I can not change access modifier for the same. However, I need to call the methods of the implementation class inside of my main class. For example, in the implementation class, I have: public void orbit() {distance++;}
I have tried: private Planet planet = new PlanetImpl, but since the PlanetImpl class is protected and in a different package, it can't find it, making the statement invalid. I have also tried leaving it null, like this
Planet planet; planet.orbit();
but it throws a NullPointerException. Is it possible to call the methods without directly referencing the implementation class?
Using anonymous inner class we can do it. Anonymous classes can implement interfaces, and i think at that time only you'll have a chance to see a class implementing an interface without the "implements" keyword.
interface Planet {
public void orbit();
}
class PlanetMain {
private Planet p = new Planet () {
public void orbit() {
System.out.println("interface Planet class executed");
}
};
}
In your case you have to create an object of that PlanetImpl class somewhere to execute the method. The interface has only the definition of that method, not the implementation.
Assuming that private/protected impl class is inner class. To call the orbit() method which is a instance method(not static), You need to create a public static factory method in the outer class and call the orbit using the instance provided by this method.
basic code example
public class PlanetImplholder{
public static Planet getInstance(){
return new PlanetImpl();
}
private static class PlanetImpl implements Planet{
#Override
public void orbit() {
System.out.println("111");
}
}
}
call the method from anywhere like below.
Planet planet = PlanetImplholder.getInstance();
planet.orbit();
Is it possible to call the methods without directly referencing the implementation class?
NO, THIS IS NOT POSSIBLE. Interface and implementation class are just declaration. To use it, you have to create class or interface instance with new. But you cannot do it, because you want to use logic of PlanetImpl, which is protected.
I think, that you do not want to implement your own class declaration and then create and use new instance of it. I think, that only one way is using reflection. Using it, you can create an instance of protected class PlanetImpl and then use it in normal ways.
Class<Planet> cls = (Class<Planet>)Class.forName("<full PlanetImpl class name, inclusing package>");
Constructor<Planet> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
Planet planet = constructor.newInstance();
planet.orbit();
I can't test it right now, but you can use reflection to access the class properties of an object.
Planet planetImpl = factory.getPlanet(); // getPlanet() returns PlanetImpl
Method orbit = planetImpl.getClass().getDeclaredMethod("orbit");
orbit.setAccessible(true);
orbit.invoke(planetImpl);
This may not work if a SecurityManager prevents access to PlanetImpl.
I create an method local Inner Class and combine with abstract class. The code work fine but I do not understand the error popup in IntelliJ about I can't set Method in inner class that extend from abstract inner class to be private.
I have to change from "Private InnerClassSubclass" to "Public InnerClassSubclass" and if I won't the error is follow:
'innerMethod()' in 'InnerClassSubclass' clashes with 'innerMethod()'
in 'InnerClass'; attempting to assign weaker access privileges
('private'); was 'public'.
I thought private is stronger privilege isn't it? only allow class within the same class to access.
I also try to change 'abstract class InnerClass' to 'private abstract class InnerClass' also got this error;
"Modifier 'private' not allowed here" at private of 'private abstract
class InnerClass'
the code is below:
public class Outerclass {
// instance method of the outer class
private void outer_Method() {
int num = 23;
// method-local inner class
abstract class InnerClass {
abstract public void innerMethod();
} // end of inner class
class InnerClassSubclass extends InnerClass {
public void innerMethod() { //if I extends, I can't use private for innerMethod here.
System.out.println("This is method inner class " + num);
}
}
// Accessing the inner class
new InnerClassSubclass().innerMethod();
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.outer_Method();
}
}
Could someone clarify me why? Thank you.
You can't restrict the visibility of methods in a subclass.
Assume an Animal class has a public method "breath()". Client code receives an Animal object and invokes that method.
Now imagine you had a Dog subclass, and you pass a doggy object. How should the client code know that his specific Animal does not offer that method?!
Thus: restricting visibility of methods is conceptually wrong, and therefore the compiler gives you an error that exactly says so.
'innerMethod()' in 'InnerClassSubclass' clashes with 'innerMethod()' in 'InnerClass'; attempting to assign weaker access privileges ('private'); was 'public'.
This is correct. You will always be able to write
InnerClass ic = new InnerClassSubclass();
ic.innerMethod(); // method is public
Consider this more general case.
static void callInnerMethod(InnerClass ic) {
ic.innerMethod(); // method is public
}
You can't make this cause a compile error when you pass an InnerClassSubclass. In a more general case you only know the actual type at runtime so it's not solvable at compile time.
InnerClass ic = Class.forName(someString).asSubClass(InnerClass.class).newInstance();
ic.innerMethod(); // this will compile as the method is public.
Firstly, you cannot make the method private because as per java overriding principles, child class cannot make the access modifier of overriding method tighter than that in it's parent class. Here, because parent class have access modifier as public, it should be made public in child class as well
Secondly, inner class can only have only two access modifier : abstract and final. You cannot declare it as private
I have a class A with static method like this:
public static class A {
public static void methodA(){...}
when I want to call methodA from class A in class B ulike this:
class B {
A.methodA();
}
the IDE says it cannot reslove reference with methodA, I know it's java syntax problem and what can I do to call methodA in class B except call it inside class B's method?
You can't call method in the body of class, as you did it in class B. In the body of class you define fields and methods of this class. If you want some actions to be performed while creating instance of some class, you need to contain these actions in the constructor, in an intialization block or in the body of additional method. Calling methods in the constructor seems to be risky if object is not being created successfully in any circumstances, it might cause problems with calling method contained in the constructor.
To call methodA() I suggest one of the following ways to achieve that:
Create appropriate method in class B and call static method of class A in the body of class B.
Create a proper initialization block to call this method.
Examples of how to call methodA() from class B, you can see below:
// 1.:
class B {
public void callA() {
A.methodA();
}
}
or
// 2.:
class B {
{
A.methodA();
}
}
Besides what the accepted answer by Przemysław Moskal states, you can also call static methods from a static block before creating any instances of class B:
class B {
static {
A.methodA();
}
}
Why is it not allowed to call the static method through the class reference returned by .class ? But instead if static method is called directly using class name it works fine. Like in example below. Are they not equal ?
package typeinfo;
class Base {
public static void method1() {
System.out.println("Inside static method1");
}
public void method2() {
System.out.println("Inside method2");
}
}
public class Sample {
public static void main(String[] args) {
Class<Base> b = Base.class;
// Works fine
Base.method1();
// Gives compilation error: cannot find symbol
// Is below statement not equal to Base.method1() ?
b.method1();
}
}
.class returns an instance of class java.lang.Class - and no, Class<Base> is not the same as Base.
Class java.lang.Class is mainly used when you use the Reflection API.
b is of type Class, so it has the methods of the Class type, and not the methods of your Base class.
You can use instances of Class to invoke methods of the classes they refer to via reflection.
Base is class name. Base.method() is java syntax for invoking a static method on class Base.
Base.class is a reference to an object of type Class, describing the class Base. Base.class.method1() does not work of course, because class Class does not have a method method1.
You can call methods of underlying class if you have to, using reflection. Consider:
Base.class.getMethod("method1").invoke(null);
I have an inner class which is present inside a method and this class has a method.
I want to use the method which is present in my inner class method outside of my current package.
Can you suggest me how to use it?
package com.a3.local;
public class OuterClass
{
public void outerMethod()
{
class InnerClazz
{
public void wakeUp()
{
System.out.println("Good Morning");
}
}
}
}
As others explained you can access to your method local defined inner-class (using an interface => see other answers).
Anyway I don't think this is the purpose of defining a method-local class.
We can access the inner class method outside the package.
We need to create an instance of the Outerclass and then create an instance of the inner class using the outer class. After that we can call it.
code from tutorial : http://www.oursland.net/tutorials/java/innerclasses/
public class InnerClassTest {
public void foo() {
System.out.println("Outer class");
}
public class ReallyInner {
public void foo() {
System.out.println("Inner class");
}
public void test() {
this.foo();
InnerClassTest.this.foo();
}
}
public static void main(String[] args) {
InnerClassTest o = new InnerClassTest();
InnerClassTest.ReallyInner i = o.new ReallyInner();
i.test();
As far as I understood the code looks like:
class Outer
{
public void someMethod()
{
class Inner{
public void methodThatShouldBeVisibleOutside() {}
}
}
}
The only way is to have the Inner class implements a publicly visible interface 'InnerInterface' and return an instance of the Inner class and invoke the methodThatShouldBeVisibleOutside:
public InnerInterface someMethod()
{
class Inner implements InnerInterface()
{
#Override
public void methodThatShouldBeVisibleOutside() {}
}
return new Inner();
}
Then
new Outer().someMethod().methodThatShouldBeVisibleOutside();
If the inner class is defined in a method, calling its methods (without reflection) requires that:
The class implement an interface accessible to the caller.
An instance of the class is accessible to the caller.
There's an example at http://java.sun.com/new2java/divelog/part5/page5.jsp .
Your class has to be public and have a name and be defined in the class body, not inside a method for you to be able to use it in other packages directly, instead of just using it by its base type or one of its interface types.
If you have a class mypackage.Outer that defines an inner class Inner, you can refer to the class using the name mypackage.Outer.Inner and import that as normal to shorten the name.
If it's static, you can create it using the new mypackage.Outer.Inner(...).
If it's not static, you have to use a different syntax to create them : myOuterInstance.new mypackage.Outer.Inner(...).
First of all, your inner class must have a public visibility and be static.
Then, there's two possibilities :
You want to call a static method of your inner class
You want to call a method on an instance of your inner class
In the first case, if the visibility are setted right, you can simply do :
OuterClass.InnerClass.myStaticMethod()
In the seconde class, you must provide a way to retrieve an instance of the inner class and simply invoke the method on the instance as you'll do with any other method.
It is also possible to call a method on a non static inner class, but this is way more complicated. A code snippet will really helps here ;)
Hope this helps.